2003-06-24 17:42:40 +04:00
|
|
|
/*
|
2004-03-14 15:20:30 +03:00
|
|
|
* QEMU System Emulator
|
2007-09-17 01:08:06 +04:00
|
|
|
*
|
2008-01-06 20:21:48 +03:00
|
|
|
* Copyright (c) 2003-2008 Fabrice Bellard
|
2007-09-17 01:08:06 +04:00
|
|
|
*
|
2003-06-25 20:20:35 +04:00
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
* THE SOFTWARE.
|
2003-06-24 17:42:40 +04:00
|
|
|
*/
|
2018-02-01 14:18:31 +03:00
|
|
|
|
2016-01-29 20:50:05 +03:00
|
|
|
#include "qemu/osdep.h"
|
2019-05-23 17:35:08 +03:00
|
|
|
#include "qemu-common.h"
|
2018-06-25 15:42:35 +03:00
|
|
|
#include "qemu/units.h"
|
2019-08-12 08:23:51 +03:00
|
|
|
#include "hw/qdev-properties.h"
|
2018-02-01 14:18:31 +03:00
|
|
|
#include "qapi/error.h"
|
2016-06-01 12:44:21 +03:00
|
|
|
#include "qemu-version.h"
|
2016-03-20 20:16:19 +03:00
|
|
|
#include "qemu/cutils.h"
|
|
|
|
#include "qemu/help_option.h"
|
2016-09-21 07:27:14 +03:00
|
|
|
#include "qemu/uuid.h"
|
2019-08-12 08:23:38 +03:00
|
|
|
#include "sysemu/reset.h"
|
2019-08-12 08:23:59 +03:00
|
|
|
#include "sysemu/runstate.h"
|
2012-12-17 21:20:04 +04:00
|
|
|
#include "sysemu/seccomp.h"
|
2019-05-23 17:35:05 +03:00
|
|
|
#include "sysemu/tcg.h"
|
2012-08-15 01:44:07 +04:00
|
|
|
|
2015-03-17 20:29:20 +03:00
|
|
|
#include "qemu/error-report.h"
|
2014-03-18 19:26:35 +04:00
|
|
|
#include "qemu/sockets.h"
|
2014-09-27 00:45:17 +04:00
|
|
|
#include "sysemu/accel.h"
|
2009-03-07 18:32:56 +03:00
|
|
|
#include "hw/usb.h"
|
2013-02-05 20:06:20 +04:00
|
|
|
#include "hw/isa/isa.h"
|
2017-02-15 15:18:54 +03:00
|
|
|
#include "hw/scsi/scsi.h"
|
2017-10-17 19:44:21 +03:00
|
|
|
#include "hw/display/vga.h"
|
2013-02-05 20:06:20 +04:00
|
|
|
#include "sysemu/watchdog.h"
|
2018-12-11 19:34:06 +03:00
|
|
|
#include "hw/firmware/smbios.h"
|
2016-12-22 19:12:33 +03:00
|
|
|
#include "hw/acpi/acpi.h"
|
2013-02-05 20:06:20 +04:00
|
|
|
#include "hw/xen/xen.h"
|
2009-10-01 18:42:33 +04:00
|
|
|
#include "hw/loader.h"
|
2013-02-04 14:37:52 +04:00
|
|
|
#include "monitor/qdev.h"
|
2012-10-24 10:43:34 +04:00
|
|
|
#include "net/net.h"
|
2009-11-25 21:48:54 +03:00
|
|
|
#include "net/slirp.h"
|
2012-12-17 21:19:49 +04:00
|
|
|
#include "monitor/monitor.h"
|
2012-11-28 15:06:30 +04:00
|
|
|
#include "ui/console.h"
|
2016-03-04 13:25:14 +03:00
|
|
|
#include "ui/input.h"
|
2012-12-17 21:20:04 +04:00
|
|
|
#include "sysemu/sysemu.h"
|
2015-02-08 21:51:16 +03:00
|
|
|
#include "sysemu/numa.h"
|
2012-12-17 21:19:49 +04:00
|
|
|
#include "exec/gdbstub.h"
|
2012-12-17 21:20:00 +04:00
|
|
|
#include "qemu/timer.h"
|
2017-01-26 16:19:46 +03:00
|
|
|
#include "chardev/char.h"
|
2014-02-07 12:26:14 +04:00
|
|
|
#include "qemu/bitmap.h"
|
2015-12-15 15:16:16 +03:00
|
|
|
#include "qemu/log.h"
|
2012-12-17 21:20:04 +04:00
|
|
|
#include "sysemu/blockdev.h"
|
2013-02-05 20:06:20 +04:00
|
|
|
#include "hw/block/block.h"
|
2017-04-17 21:26:27 +03:00
|
|
|
#include "migration/misc.h"
|
2017-04-20 15:25:55 +03:00
|
|
|
#include "migration/snapshot.h"
|
2017-04-24 19:53:30 +03:00
|
|
|
#include "migration/global_state.h"
|
2013-04-02 20:28:41 +04:00
|
|
|
#include "sysemu/tpm.h"
|
2012-12-17 21:20:04 +04:00
|
|
|
#include "sysemu/dma.h"
|
2017-05-08 23:57:35 +03:00
|
|
|
#include "hw/audio/soundhw.h"
|
2009-03-07 18:32:56 +03:00
|
|
|
#include "audio/audio.h"
|
2016-03-15 18:47:38 +03:00
|
|
|
#include "sysemu/cpus.h"
|
2016-10-27 09:42:53 +03:00
|
|
|
#include "migration/colo.h"
|
2018-03-12 20:20:59 +03:00
|
|
|
#include "migration/postcopy-ram.h"
|
2012-12-17 21:20:04 +04:00
|
|
|
#include "sysemu/kvm.h"
|
2017-01-10 13:59:57 +03:00
|
|
|
#include "sysemu/hax.h"
|
block: Initial implementation of -blockdev
The new command line option -blockdev works like QMP command
blockdev-add.
The option argument may be given in JSON syntax, exactly as in QMP.
Example usage:
-blockdev '{"node-name": "foo", "driver": "raw", "file": {"driver": "file", "filename": "foo.img"} }'
The JSON argument doesn't exactly blend into the existing option
syntax, so the traditional KEY=VALUE,... syntax is also supported,
using dotted keys to do the nesting:
-blockdev node-name=foo,driver=raw,file.driver=file,file.filename=foo.img
This does not yet support lists, but that will be addressed shortly.
Note that calling qmp_blockdev_add() (say via qmp_marshal_block_add())
right away would crash. We need to stash the configuration for later
instead. This is crudely done, and bypasses QemuOpts, even though
storing configuration is what QemuOpts is for. Need to revamp option
infrastructure to support QAPI types like BlockdevOptions.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1488317230-26248-22-git-send-email-armbru@redhat.com>
2017-03-01 00:27:07 +03:00
|
|
|
#include "qapi/qobject-input-visitor.h"
|
2012-12-17 21:20:00 +04:00
|
|
|
#include "qemu/option.h"
|
|
|
|
#include "qemu/config-file.h"
|
2010-06-10 13:42:25 +04:00
|
|
|
#include "qemu-options.h"
|
2012-12-17 21:20:00 +04:00
|
|
|
#include "qemu/main-loop.h"
|
2010-06-15 00:34:41 +04:00
|
|
|
#ifdef CONFIG_VIRTFS
|
2010-04-29 16:14:43 +04:00
|
|
|
#include "fsdev/qemu-fsdev.h"
|
|
|
|
#endif
|
2012-12-17 21:20:04 +04:00
|
|
|
#include "sysemu/qtest.h"
|
2009-03-07 18:32:56 +03:00
|
|
|
|
2012-10-24 13:12:21 +04:00
|
|
|
#include "disas/disas.h"
|
2003-06-30 14:03:06 +04:00
|
|
|
|
2017-01-25 19:14:15 +03:00
|
|
|
#include "trace-root.h"
|
2011-08-31 22:31:03 +04:00
|
|
|
#include "trace/control.h"
|
2017-07-24 17:28:22 +03:00
|
|
|
#include "qemu/plugin.h"
|
2012-12-17 21:20:00 +04:00
|
|
|
#include "qemu/queue.h"
|
2012-12-17 21:20:04 +04:00
|
|
|
#include "sysemu/arch_init.h"
|
2009-09-12 11:36:22 +04:00
|
|
|
|
2010-03-11 17:13:27 +03:00
|
|
|
#include "ui/qemu-spice.h"
|
2012-06-25 23:36:33 +04:00
|
|
|
#include "qapi/string-input-visitor.h"
|
2014-06-10 15:15:15 +04:00
|
|
|
#include "qapi/opts-visitor.h"
|
2018-05-07 12:55:36 +03:00
|
|
|
#include "qapi/clone-visitor.h"
|
2014-06-18 10:43:33 +04:00
|
|
|
#include "qom/object_interfaces.h"
|
2019-05-13 16:43:57 +03:00
|
|
|
#include "hw/semihosting/semihost.h"
|
2015-07-01 20:10:29 +03:00
|
|
|
#include "crypto/init.h"
|
2015-09-17 19:24:33 +03:00
|
|
|
#include "sysemu/replay.h"
|
2018-02-11 12:36:01 +03:00
|
|
|
#include "qapi/qapi-events-run-state.h"
|
|
|
|
#include "qapi/qapi-visit-block-core.h"
|
2018-05-07 12:55:36 +03:00
|
|
|
#include "qapi/qapi-visit-ui.h"
|
2018-02-27 02:13:27 +03:00
|
|
|
#include "qapi/qapi-commands-block-core.h"
|
|
|
|
#include "qapi/qapi-commands-run-state.h"
|
2018-11-22 10:16:13 +03:00
|
|
|
#include "qapi/qapi-commands-ui.h"
|
2015-09-17 19:25:13 +03:00
|
|
|
#include "qapi/qmp/qerror.h"
|
2016-09-08 12:28:51 +03:00
|
|
|
#include "sysemu/iothread.h"
|
2019-03-14 23:06:29 +03:00
|
|
|
#include "qemu/guest-random.h"
|
2010-03-11 17:13:27 +03:00
|
|
|
|
virtio-console: qdev conversion, new virtio-serial-bus
This commit converts the virtio-console device to create a new
virtio-serial bus that can host console and generic serial ports. The
file hosting this code is now called virtio-serial-bus.c.
The virtio console is now a very simple qdev device that sits on the
virtio-serial-bus and communicates between the bus and qemu's chardevs.
This commit also includes a few changes to the virtio backing code for
pci and s390 to spawn the virtio-serial bus.
As a result of the qdev conversion, we get rid of a lot of legacy code.
The old-style way of instantiating a virtio console using
-virtioconsole ...
is maintained, but the new, preferred way is to use
-device virtio-serial -device virtconsole,chardev=...
With this commit, multiple devices as well as multiple ports with a
single device can be supported.
For multiple ports support, each port gets an IO vq pair. Since the
guest needs to know in advance how many vqs a particular device will
need, we have to set this number as a property of the virtio-serial
device and also as a config option.
In addition, we also spawn a pair of control IO vqs. This is an internal
channel meant for guest-host communication for things like port
open/close, sending port properties over to the guest, etc.
This commit is a part of a series of other commits to get the full
implementation of multiport support. Future commits will add other
support as well as ride on the savevm version that we bump up here.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-01-19 22:06:52 +03:00
|
|
|
#define MAX_VIRTIO_CONSOLES 1
|
|
|
|
|
2013-03-08 14:42:24 +04:00
|
|
|
static const char *data_dir[16];
|
|
|
|
static int data_dir_idx;
|
2007-10-05 17:08:35 +04:00
|
|
|
const char *bios_name = NULL;
|
2008-09-28 04:42:12 +04:00
|
|
|
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
|
2014-11-20 11:49:44 +03:00
|
|
|
int display_opengl;
|
2004-12-12 19:56:30 +03:00
|
|
|
const char* keyboard_layout = NULL;
|
2009-10-02 01:12:16 +04:00
|
|
|
ram_addr_t ram_size;
|
2010-03-02 02:25:08 +03:00
|
|
|
const char *mem_path = NULL;
|
|
|
|
int mem_prealloc = 0; /* force preallocation of physical target memory */
|
2014-09-23 14:42:24 +04:00
|
|
|
bool enable_mlock = false;
|
2018-06-22 22:22:05 +03:00
|
|
|
bool enable_cpu_pm = false;
|
2004-03-15 00:44:30 +03:00
|
|
|
int nb_nics;
|
2005-11-16 01:16:05 +03:00
|
|
|
NICInfo nd_table[MAX_NICS];
|
2009-07-28 01:17:51 +04:00
|
|
|
int autostart;
|
2018-10-18 10:12:53 +03:00
|
|
|
static enum {
|
|
|
|
RTC_BASE_UTC,
|
|
|
|
RTC_BASE_LOCALTIME,
|
|
|
|
RTC_BASE_DATETIME,
|
|
|
|
} rtc_base_type = RTC_BASE_UTC;
|
2018-10-18 10:12:54 +03:00
|
|
|
static time_t rtc_ref_start_datetime;
|
|
|
|
static int rtc_realtime_clock_offset; /* used only with QEMU_CLOCK_REALTIME */
|
|
|
|
static int rtc_host_datetime_offset = -1; /* valid & used only with
|
|
|
|
RTC_BASE_DATETIME */
|
2013-08-21 19:03:04 +04:00
|
|
|
QEMUClockType rtc_clock;
|
2009-12-08 15:11:45 +03:00
|
|
|
int vga_interface_type = VGA_NONE;
|
2018-02-02 14:10:14 +03:00
|
|
|
static DisplayOptions dpy;
|
2018-06-22 15:28:42 +03:00
|
|
|
static int num_serial_hds;
|
|
|
|
static Chardev **serial_hds;
|
2016-12-07 16:20:22 +03:00
|
|
|
Chardev *parallel_hds[MAX_PARALLEL_PORTS];
|
2005-04-30 20:10:35 +04:00
|
|
|
int win2k_install_hack = 0;
|
2009-04-06 00:08:59 +04:00
|
|
|
int singlestep = 0;
|
2006-05-04 02:02:44 +04:00
|
|
|
int acpi_enabled = 1;
|
2008-12-18 02:28:44 +03:00
|
|
|
int no_hpet = 0;
|
2006-06-14 20:03:05 +04:00
|
|
|
int fd_bootchk = 1;
|
2012-10-28 15:04:47 +04:00
|
|
|
static int no_reboot;
|
2008-04-12 01:35:52 +04:00
|
|
|
int no_shutdown = 0;
|
2007-04-30 05:48:07 +04:00
|
|
|
int graphic_rotate = 0;
|
2009-08-21 12:31:34 +04:00
|
|
|
const char *watchdog;
|
2010-12-08 14:35:07 +03:00
|
|
|
QEMUOptionRom option_rom[MAX_OPTION_ROMS];
|
2007-01-05 20:39:04 +03:00
|
|
|
int nb_option_roms;
|
2007-07-28 02:08:46 +04:00
|
|
|
int old_param = 0;
|
2007-03-19 18:17:08 +03:00
|
|
|
const char *qemu_name;
|
2007-06-22 01:08:02 +04:00
|
|
|
int alt_grab = 0;
|
2009-09-18 00:48:04 +04:00
|
|
|
int ctrl_grab = 0;
|
2007-05-01 18:16:52 +04:00
|
|
|
unsigned int nb_prom_envs = 0;
|
|
|
|
const char *prom_envs[MAX_PROM_ENVS];
|
2009-07-02 02:19:02 +04:00
|
|
|
int boot_menu;
|
2014-10-07 12:00:05 +04:00
|
|
|
bool boot_strict;
|
2011-07-27 14:04:55 +04:00
|
|
|
uint8_t *boot_splash_filedata;
|
Revert "migration: move only_migratable to MigrationState"
This reverts commit 3df663e575f1876d7f3bc684f80e72fca0703d39.
This reverts commit b605c47b57b58e61a901a50a0762dccf43d94783.
Command line option --only-migratable is for disallowing any
configuration that can block migration.
Initially, --only-migratable set global variable @only_migratable.
Commit 3df663e575 "migration: move only_migratable to MigrationState"
replaced it by MigrationState member @only_migratable. That was a
mistake.
First, it doesn't make sense on the design level. MigrationState
captures the state of an individual migration, but --only-migratable
isn't a property of an individual migration, it's a restriction on
QEMU configuration. With fault tolerance, we could have several
migrations at once. --only-migratable would certainly protect all of
them. Storing it in MigrationState feels inappropriate.
Second, it contributes to a dependency cycle that manifests itself as
a bug now.
Putting @only_migratable into MigrationState means its available only
after migration_object_init().
We can't set it before migration_object_init(), so we delay setting it
with a global property (this is fixup commit b605c47b57 "migration:
fix handling for --only-migratable").
We can't get it before migration_object_init(), so anything that uses
it can only run afterwards.
Since migrate_add_blocker() needs to obey --only-migratable, any code
adding migration blockers can run only afterwards. This contributes
to the following dependency cycle:
* configure_blockdev() must run before machine_set_property()
so machine properties can refer to block backends
* machine_set_property() before configure_accelerator()
so machine properties like kvm-irqchip get applied
* configure_accelerator() before migration_object_init()
so that Xen's accelerator compat properties get applied.
* migration_object_init() before configure_blockdev()
so configure_blockdev() can add migration blockers
The cycle was closed when recent commit cda4aa9a5a0 "Create block
backends before setting machine properties" added the first
dependency, and satisfied it by violating the last one. Broke block
backends that add migration blockers.
Moving @only_migratable into MigrationState was a mistake. Revert it.
This doesn't quite break the "migration_object_init() before
configure_blockdev() dependency, since migrate_add_blocker() still has
another dependency on migration_object_init(). To be addressed the
next commit.
Note that the reverted commit made -only-migratable sugar for -global
migration.only-migratable=on below the hood. Documentation has only
ever mentioned -only-migratable. This commit removes the arcane &
undocumented alternative to -only-migratable again. Nobody should be
using it.
Conflicts:
include/migration/misc.h
migration/migration.c
migration/migration.h
vl.c
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20190401090827.20793-3-armbru@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
2019-04-01 12:08:24 +03:00
|
|
|
int only_migratable; /* turn it off unless user states otherwise */
|
qmp: query-current-machine with wakeup-suspend-support
When issuing the qmp/hmp 'system_wakeup' command, what happens in a
nutshell is:
- qmp_system_wakeup_request set runstate to RUNNING, sets a wakeup_reason
and notify the event
- in the main_loop, all vcpus are paused, a system reset is issued, all
subscribers of wakeup_notifiers receives a notification, vcpus are then
resumed and the wake up QAPI event is fired
Note that this procedure alone doesn't ensure that the guest will awake
from SUSPENDED state - the subscribers of the wake up event must take
action to resume the guest, otherwise the guest will simply reboot. At
this moment, only the ACPI machines via acpi_pm1_cnt_init and xen_hvm_init
have wake-up from suspend support.
However, only the presence of 'system_wakeup' is required for QGA to
support 'guest-suspend-ram' and 'guest-suspend-hybrid' at this moment.
This means that the user/management will expect to suspend the guest using
one of those suspend commands and then resume execution using system_wakeup,
regardless of the support offered in system_wakeup in the first place.
This patch creates a new API called query-current-machine [1], that holds
a new flag called 'wakeup-suspend-support' that indicates if the guest
supports wake up from suspend via system_wakeup. The machine is considered
to implement wake-up support if a call to a new 'qemu_register_wakeup_support'
is made during its init, as it is now being done inside acpi_pm1_cnt_init
and xen_hvm_init. This allows for any other machine type to declare wake-up
support regardless of ACPI state or wakeup_notifiers subscription, making easier
for newer implementations that might have their own mechanisms in the future.
This is the expected output of query-current-machine when running a x86
guest:
{"execute" : "query-current-machine"}
{"return": {"wakeup-suspend-support": true}}
Running the same x86 guest, but with the --no-acpi option:
{"execute" : "query-current-machine"}
{"return": {"wakeup-suspend-support": false}}
This is the output when running a pseries guest:
{"execute" : "query-current-machine"}
{"return": {"wakeup-suspend-support": false}}
With this extra tool, management can avoid situations where a guest
that does not have proper suspend/wake capabilities ends up in
inconsistent state (e.g.
https://github.com/open-power-host-os/qemu/issues/31).
[1] the decision of creating the query-current-machine API is based
on discussions in the QEMU mailing list where it was decided that
query-target wasn't a proper place to store the wake-up flag, neither
was query-machines because this isn't a static property of the
machine object. This new API can then be used to store other
dynamic machine properties that are scattered around the code
ATM. More info at:
https://lists.gnu.org/archive/html/qemu-devel/2018-05/msg04235.html
Reported-by: Balamuruhan S <bala24@linux.vnet.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20181205194701.17836-2-danielhb413@gmail.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-05 22:46:59 +03:00
|
|
|
bool wakeup_suspend_enabled;
|
2003-06-24 17:42:40 +04:00
|
|
|
|
2014-07-25 13:56:29 +04:00
|
|
|
int icount_align_option;
|
2010-12-08 14:35:05 +03:00
|
|
|
|
2016-09-21 07:27:22 +03:00
|
|
|
/* The bytes in qemu_uuid are in the order specified by RFC4122, _not_ in the
|
smbios: Encode UUID according to SMBIOS specification
Differently from older versions, SMBIOS version 2.6 is explicit about
the encoding of UUID fields:
> Although RFC 4122 recommends network byte order for all fields, the PC
> industry (including the ACPI, UEFI, and Microsoft specifications) has
> consistently used little-endian byte encoding for the first three fields:
> time_low, time_mid, time_hi_and_version. The same encoding, also known as
> wire format, should also be used for the SMBIOS representation of the UUID.
>
> The UUID {00112233-4455-6677-8899-AABBCCDDEEFF} would thus be represented
> as 33 22 11 00 55 44 77 66 88 99 AA BB CC DD EE FF.
The dmidecode tool implements this and decodes the above "wire format"
when SMBIOS version >= 2.6. We moved from SMBIOS version 2.4 to 2.8 when
we started building the SMBIOS entry point inside QEMU, on commit
c97294ec1b9e36887e119589d456557d72ab37b5.
Change smbios_build_type_1_table() to encode the UUID as specified.
To make sure we won't change the guest-visible UUID when upgrading to a
newer QEMU version, keep the old behavior on pc-*-2.1 and older.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-10-29 16:26:08 +03:00
|
|
|
* little-endian "wire format" described in the SMBIOS 2.6 specification.
|
|
|
|
*/
|
2016-09-21 07:27:22 +03:00
|
|
|
QemuUUID qemu_uuid;
|
smbios: Make multiple -smbios type= accumulate sanely
Currently, -smbios type=T,NAME=VAL,... adds one field (T,NAME) with
value VAL to fw_cfg for each unique NAME. If NAME occurs multiple
times, the last one's VAL is used (before the QemuOpts conversion, the
first one was used).
Multiple -smbios can add multiple fields with the same (T, NAME).
SeaBIOS reads all of them from fw_cfg, but uses only the first field
(T, NAME). The others are ignored.
"First one wins, subsequent ones get ignored silently" isn't nice. We
commonly let the last option win. Useful, because it lets you
-readconfig first, then selectively override with command line
options.
Clean up -smbios to work the common way. Accumulate the settings,
with later ones overwriting earlier ones. Put the result into fw_cfg
(no more useless duplicates).
Bonus cleanup: qemu_uuid_parse() no longer sets SMBIOS system uuid by
side effect.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2013-08-16 17:18:31 +04:00
|
|
|
bool qemu_uuid_set;
|
2008-09-18 22:29:08 +04:00
|
|
|
|
2010-06-04 16:08:07 +04:00
|
|
|
static NotifierList exit_notifiers =
|
|
|
|
NOTIFIER_LIST_INITIALIZER(exit_notifiers);
|
|
|
|
|
2010-12-08 14:35:08 +03:00
|
|
|
static NotifierList machine_init_done_notifiers =
|
|
|
|
NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
|
|
|
|
|
2013-01-24 09:03:27 +04:00
|
|
|
bool xen_allowed;
|
2010-03-29 23:23:49 +04:00
|
|
|
uint32_t xen_domid;
|
|
|
|
enum xen_mode xen_mode = XEN_EMULATE;
|
2017-03-22 12:39:15 +03:00
|
|
|
bool xen_domid_restrict;
|
2010-03-29 23:23:49 +04:00
|
|
|
|
2014-03-10 18:37:40 +04:00
|
|
|
static int has_defaults = 1;
|
2009-12-08 15:11:41 +03:00
|
|
|
static int default_serial = 1;
|
2009-12-08 15:11:42 +03:00
|
|
|
static int default_parallel = 1;
|
2009-12-08 15:11:43 +03:00
|
|
|
static int default_monitor = 1;
|
2009-12-16 16:25:39 +03:00
|
|
|
static int default_floppy = 1;
|
|
|
|
static int default_cdrom = 1;
|
|
|
|
static int default_sdcard = 1;
|
2012-05-10 11:39:17 +04:00
|
|
|
static int default_vga = 1;
|
2016-05-12 17:17:16 +03:00
|
|
|
static int default_net = 1;
|
2009-12-08 15:11:41 +03:00
|
|
|
|
|
|
|
static struct {
|
|
|
|
const char *driver;
|
|
|
|
int *flag;
|
|
|
|
} default_list[] = {
|
2009-12-08 15:11:42 +03:00
|
|
|
{ .driver = "isa-serial", .flag = &default_serial },
|
|
|
|
{ .driver = "isa-parallel", .flag = &default_parallel },
|
2009-12-16 16:25:40 +03:00
|
|
|
{ .driver = "isa-fdc", .flag = &default_floppy },
|
2016-10-27 23:29:13 +03:00
|
|
|
{ .driver = "floppy", .flag = &default_floppy },
|
2011-05-18 20:31:02 +04:00
|
|
|
{ .driver = "ide-cd", .flag = &default_cdrom },
|
|
|
|
{ .driver = "ide-hd", .flag = &default_cdrom },
|
2009-12-16 16:25:40 +03:00
|
|
|
{ .driver = "ide-drive", .flag = &default_cdrom },
|
2011-05-18 20:31:02 +04:00
|
|
|
{ .driver = "scsi-cd", .flag = &default_cdrom },
|
2017-02-20 23:41:19 +03:00
|
|
|
{ .driver = "scsi-hd", .flag = &default_cdrom },
|
2012-05-10 11:39:17 +04:00
|
|
|
{ .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 },
|
2014-09-10 16:28:48 +04:00
|
|
|
{ .driver = "virtio-vga", .flag = &default_vga },
|
2019-03-09 20:21:40 +03:00
|
|
|
{ .driver = "ati-vga", .flag = &default_vga },
|
2019-05-24 16:09:46 +03:00
|
|
|
{ .driver = "vhost-user-vga", .flag = &default_vga },
|
2009-12-08 15:11:41 +03:00
|
|
|
};
|
|
|
|
|
2012-11-26 19:03:42 +04:00
|
|
|
static QemuOptsList qemu_rtc_opts = {
|
|
|
|
.name = "rtc",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
|
2018-10-18 10:12:54 +03:00
|
|
|
.merge_lists = true,
|
2012-11-26 19:03:42 +04:00
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "base",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},{
|
|
|
|
.name = "clock",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},{
|
|
|
|
.name = "driftfix",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static QemuOptsList qemu_option_rom_opts = {
|
|
|
|
.name = "option-rom",
|
|
|
|
.implied_opt_name = "romfile",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_option_rom_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "bootindex",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
}, {
|
|
|
|
.name = "romfile",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static QemuOptsList qemu_machine_opts = {
|
|
|
|
.name = "machine",
|
|
|
|
.implied_opt_name = "type",
|
|
|
|
.merge_lists = true,
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head),
|
|
|
|
.desc = {
|
2014-12-16 19:58:05 +03:00
|
|
|
/*
|
|
|
|
* no elements => accept any
|
|
|
|
* sanity checking will happen later
|
|
|
|
* when setting machine properties
|
|
|
|
*/
|
|
|
|
{ }
|
2012-11-26 19:03:42 +04:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2017-02-23 21:29:08 +03:00
|
|
|
static QemuOptsList qemu_accel_opts = {
|
|
|
|
.name = "accel",
|
|
|
|
.implied_opt_name = "accel",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_accel_opts.head),
|
|
|
|
.desc = {
|
2019-11-13 12:36:01 +03:00
|
|
|
/*
|
|
|
|
* no elements => accept any
|
|
|
|
* sanity checking will happen later
|
|
|
|
* when setting accelerator properties
|
|
|
|
*/
|
|
|
|
{ }
|
2017-02-23 21:29:08 +03:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2012-11-26 19:03:42 +04:00
|
|
|
static QemuOptsList qemu_boot_opts = {
|
|
|
|
.name = "boot-opts",
|
2013-06-14 15:15:01 +04:00
|
|
|
.implied_opt_name = "order",
|
|
|
|
.merge_lists = true,
|
2012-11-26 19:03:42 +04:00
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_boot_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "order",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
}, {
|
|
|
|
.name = "once",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
}, {
|
|
|
|
.name = "menu",
|
2013-06-14 15:15:01 +04:00
|
|
|
.type = QEMU_OPT_BOOL,
|
2012-11-26 19:03:42 +04:00
|
|
|
}, {
|
|
|
|
.name = "splash",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
}, {
|
|
|
|
.name = "splash-time",
|
2018-11-21 08:10:24 +03:00
|
|
|
.type = QEMU_OPT_NUMBER,
|
2012-11-26 19:03:42 +04:00
|
|
|
}, {
|
|
|
|
.name = "reboot-timeout",
|
2018-11-21 08:10:25 +03:00
|
|
|
.type = QEMU_OPT_NUMBER,
|
2013-03-19 10:23:27 +04:00
|
|
|
}, {
|
|
|
|
.name = "strict",
|
2013-12-09 15:53:15 +04:00
|
|
|
.type = QEMU_OPT_BOOL,
|
2012-11-26 19:03:42 +04:00
|
|
|
},
|
|
|
|
{ /*End of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static QemuOptsList qemu_add_fd_opts = {
|
|
|
|
.name = "add-fd",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_add_fd_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "fd",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
.help = "file descriptor of which a duplicate is added to fd set",
|
|
|
|
},{
|
|
|
|
.name = "set",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
.help = "ID of the fd set to add fd to",
|
|
|
|
},{
|
|
|
|
.name = "opaque",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "free-form string used to describe fd",
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static QemuOptsList qemu_object_opts = {
|
|
|
|
.name = "object",
|
|
|
|
.implied_opt_name = "qom-type",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
Support for TPM command line options
This patch adds support for TPM command line options.
The command line options supported here are
./qemu-... -tpmdev passthrough,path=<path to TPM device>,id=<id>
-device tpm-tis,tpmdev=<id>,id=<other id>
and
./qemu-... -tpmdev help
where the latter works similar to -soundhw help and shows a list of
available TPM backends (for example 'passthrough').
Using the type parameter, the backend is chosen, i.e., 'passthrough' for the
passthrough driver. The interpretation of the other parameters along
with determining whether enough parameters were provided is pushed into
the backend driver, which needs to implement the interface function
'create' and return a TPMDriverOpts structure if the VM can be started or
'NULL' if not enough or bad parameters were provided.
Monitor support for 'info tpm' has been added. It for example prints the
following:
(qemu) info tpm
TPM devices:
tpm0: model=tpm-tis
\ tpm0: type=passthrough,path=/dev/tpm0,cancel-path=/sys/devices/pnp0/00:09/cancel
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
Reviewed-by: Joel Schopp <jschopp@linux.vnet.ibm.com>
Message-id: 1361987275-26289-2-git-send-email-stefanb@linux.vnet.ibm.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-02-27 21:47:49 +04:00
|
|
|
static QemuOptsList qemu_tpmdev_opts = {
|
|
|
|
.name = "tpmdev",
|
|
|
|
.implied_opt_name = "type",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_tpmdev_opts.head),
|
|
|
|
.desc = {
|
2013-04-22 18:41:39 +04:00
|
|
|
/* options are defined in the TPM backends */
|
Support for TPM command line options
This patch adds support for TPM command line options.
The command line options supported here are
./qemu-... -tpmdev passthrough,path=<path to TPM device>,id=<id>
-device tpm-tis,tpmdev=<id>,id=<other id>
and
./qemu-... -tpmdev help
where the latter works similar to -soundhw help and shows a list of
available TPM backends (for example 'passthrough').
Using the type parameter, the backend is chosen, i.e., 'passthrough' for the
passthrough driver. The interpretation of the other parameters along
with determining whether enough parameters were provided is pushed into
the backend driver, which needs to implement the interface function
'create' and return a TPMDriverOpts structure if the VM can be started or
'NULL' if not enough or bad parameters were provided.
Monitor support for 'info tpm' has been added. It for example prints the
following:
(qemu) info tpm
TPM devices:
tpm0: model=tpm-tis
\ tpm0: type=passthrough,path=/dev/tpm0,cancel-path=/sys/devices/pnp0/00:09/cancel
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
Reviewed-by: Joel Schopp <jschopp@linux.vnet.ibm.com>
Message-id: 1361987275-26289-2-git-send-email-stefanb@linux.vnet.ibm.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-02-27 21:47:49 +04:00
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2013-04-19 18:42:06 +04:00
|
|
|
static QemuOptsList qemu_realtime_opts = {
|
|
|
|
.name = "realtime",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_realtime_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "mlock",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-06-22 22:22:05 +03:00
|
|
|
static QemuOptsList qemu_overcommit_opts = {
|
|
|
|
.name = "overcommit",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_overcommit_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "mem-lock",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "cpu-pm",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2013-07-04 07:02:46 +04:00
|
|
|
static QemuOptsList qemu_msg_opts = {
|
|
|
|
.name = "msg",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_msg_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "timestamp",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2014-01-30 14:20:30 +04:00
|
|
|
static QemuOptsList qemu_name_opts = {
|
|
|
|
.name = "name",
|
|
|
|
.implied_opt_name = "guest",
|
|
|
|
.merge_lists = true,
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_name_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "guest",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "Sets the name of the guest.\n"
|
|
|
|
"This name will be displayed in the SDL window caption.\n"
|
|
|
|
"The name will also be used for the VNC server",
|
|
|
|
}, {
|
|
|
|
.name = "process",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "Sets the name of the QEMU process, as shown in top etc",
|
2014-01-30 14:20:31 +04:00
|
|
|
}, {
|
|
|
|
.name = "debug-threads",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
.help = "When enabled, name the individual threads; defaults off.\n"
|
|
|
|
"NOTE: The thread names are for debugging and not a\n"
|
|
|
|
"stable API.",
|
2014-01-30 14:20:30 +04:00
|
|
|
},
|
|
|
|
{ /* End of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2013-11-27 04:27:35 +04:00
|
|
|
static QemuOptsList qemu_mem_opts = {
|
|
|
|
.name = "memory",
|
|
|
|
.implied_opt_name = "size",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
|
|
|
|
.merge_lists = true,
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "size",
|
|
|
|
.type = QEMU_OPT_SIZE,
|
|
|
|
},
|
2014-06-02 17:25:02 +04:00
|
|
|
{
|
|
|
|
.name = "slots",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "maxmem",
|
|
|
|
.type = QEMU_OPT_SIZE,
|
|
|
|
},
|
2013-11-27 04:27:35 +04:00
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2014-07-25 13:56:28 +04:00
|
|
|
static QemuOptsList qemu_icount_opts = {
|
|
|
|
.name = "icount",
|
|
|
|
.implied_opt_name = "shift",
|
|
|
|
.merge_lists = true,
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_icount_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "shift",
|
|
|
|
.type = QEMU_OPT_STRING,
|
2014-07-25 13:56:29 +04:00
|
|
|
}, {
|
|
|
|
.name = "align",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
2015-05-29 18:14:05 +03:00
|
|
|
}, {
|
|
|
|
.name = "sleep",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
2015-09-17 19:25:18 +03:00
|
|
|
}, {
|
|
|
|
.name = "rr",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
}, {
|
|
|
|
.name = "rrfile",
|
|
|
|
.type = QEMU_OPT_STRING,
|
2017-01-24 10:17:47 +03:00
|
|
|
}, {
|
|
|
|
.name = "rrsnapshot",
|
|
|
|
.type = QEMU_OPT_STRING,
|
2014-07-25 13:56:28 +04:00
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2015-04-29 18:21:53 +03:00
|
|
|
static QemuOptsList qemu_fw_cfg_opts = {
|
|
|
|
.name = "fw_cfg",
|
|
|
|
.implied_opt_name = "name",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_fw_cfg_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "name",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "Sets the fw_cfg name of the blob to be inserted",
|
|
|
|
}, {
|
|
|
|
.name = "file",
|
|
|
|
.type = QEMU_OPT_STRING,
|
2018-10-19 19:49:29 +03:00
|
|
|
.help = "Sets the name of the file from which "
|
2015-04-29 18:21:53 +03:00
|
|
|
"the fw_cfg blob will be loaded",
|
2015-09-29 19:29:01 +03:00
|
|
|
}, {
|
|
|
|
.name = "string",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "Sets content of the blob to be inserted from a string",
|
2015-04-29 18:21:53 +03:00
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2013-07-04 17:09:19 +04:00
|
|
|
/**
|
|
|
|
* Get machine options
|
|
|
|
*
|
|
|
|
* Returns: machine options (never null).
|
|
|
|
*/
|
|
|
|
QemuOpts *qemu_get_machine_opts(void)
|
|
|
|
{
|
2014-03-06 13:39:24 +04:00
|
|
|
return qemu_find_opts_singleton("machine");
|
2013-07-04 17:09:19 +04:00
|
|
|
}
|
|
|
|
|
2012-08-06 12:24:55 +04:00
|
|
|
const char *qemu_get_vm_name(void)
|
|
|
|
{
|
|
|
|
return qemu_name;
|
|
|
|
}
|
|
|
|
|
2011-07-27 14:04:55 +04:00
|
|
|
static void res_free(void)
|
|
|
|
{
|
2015-08-26 15:02:53 +03:00
|
|
|
g_free(boot_splash_filedata);
|
|
|
|
boot_splash_filedata = NULL;
|
2011-07-27 14:04:55 +04:00
|
|
|
}
|
|
|
|
|
2015-03-13 15:35:14 +03:00
|
|
|
static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp)
|
2009-12-08 15:11:41 +03:00
|
|
|
{
|
|
|
|
const char *driver = qemu_opt_get(opts, "driver");
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!driver)
|
|
|
|
return 0;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(default_list); i++) {
|
|
|
|
if (strcmp(default_list[i].driver, driver) != 0)
|
|
|
|
continue;
|
|
|
|
*(default_list[i].flag) = 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-07-29 22:04:45 +04:00
|
|
|
/***********************************************************/
|
|
|
|
/* QEMU state */
|
|
|
|
|
2018-05-11 20:24:43 +03:00
|
|
|
static RunState current_run_state = RUN_STATE_PRECONFIG;
|
2011-07-29 22:04:45 +04:00
|
|
|
|
qapi: Don't let implicit enum MAX member collide
Now that we guarantee the user doesn't have any enum values
beginning with a single underscore, we can use that for our
own purposes. Renaming ENUM_MAX to ENUM__MAX makes it obvious
that the sentinel is generated.
This patch was mostly generated by applying a temporary patch:
|diff --git a/scripts/qapi.py b/scripts/qapi.py
|index e6d014b..b862ec9 100644
|--- a/scripts/qapi.py
|+++ b/scripts/qapi.py
|@@ -1570,6 +1570,7 @@ const char *const %(c_name)s_lookup[] = {
| max_index = c_enum_const(name, 'MAX', prefix)
| ret += mcgen('''
| [%(max_index)s] = NULL,
|+// %(max_index)s
| };
| ''',
| max_index=max_index)
then running:
$ cat qapi-{types,event}.c tests/test-qapi-types.c |
sed -n 's,^// \(.*\)MAX,s|\1MAX|\1_MAX|g,p' > list
$ git grep -l _MAX | xargs sed -i -f list
The only things not generated are the changes in scripts/qapi.py.
Rejecting enum members named 'MAX' is now useless, and will be dropped
in the next patch.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1447836791-369-23-git-send-email-eblake@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
[Rebased to current master, commit message tweaked]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-11-18 11:52:57 +03:00
|
|
|
/* We use RUN_STATE__MAX but any invalid value will do */
|
|
|
|
static RunState vmstop_requested = RUN_STATE__MAX;
|
2014-06-05 16:53:58 +04:00
|
|
|
static QemuMutex vmstop_lock;
|
|
|
|
|
2011-09-05 23:36:31 +04:00
|
|
|
typedef struct {
|
|
|
|
RunState from;
|
|
|
|
RunState to;
|
|
|
|
} RunStateTransition;
|
|
|
|
|
|
|
|
static const RunStateTransition runstate_transitions_def[] = {
|
|
|
|
/* from -> to */
|
2018-05-11 20:24:43 +03:00
|
|
|
{ RUN_STATE_PRECONFIG, RUN_STATE_PRELAUNCH },
|
|
|
|
/* Early switch to inmigrate state to allow -incoming CLI option work
|
|
|
|
* as it used to. TODO: delay actual switching to inmigrate state to
|
|
|
|
* the point after machine is built and remove this hack.
|
|
|
|
*/
|
|
|
|
{ RUN_STATE_PRECONFIG, RUN_STATE_INMIGRATE },
|
|
|
|
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_DEBUG, RUN_STATE_RUNNING },
|
2013-12-03 16:00:15 +04:00
|
|
|
{ RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
|
2016-02-13 16:26:26 +03:00
|
|
|
{ RUN_STATE_DEBUG, RUN_STATE_PRELAUNCH },
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2014-10-08 14:47:08 +04:00
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_INTERNAL_ERROR },
|
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_IO_ERROR },
|
2012-10-19 18:45:24 +04:00
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_PAUSED },
|
2014-10-08 14:47:08 +04:00
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_RUNNING },
|
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_SHUTDOWN },
|
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_SUSPENDED },
|
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_WATCHDOG },
|
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED },
|
2015-07-28 16:28:28 +03:00
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_FINISH_MIGRATE },
|
2016-02-15 21:40:04 +03:00
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_PRELAUNCH },
|
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_POSTMIGRATE },
|
2016-10-27 09:42:58 +03:00
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_COLO },
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
|
2011-10-14 18:18:09 +04:00
|
|
|
{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
|
2016-02-13 16:26:26 +03:00
|
|
|
{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PRELAUNCH },
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },
|
2011-10-14 18:18:09 +04:00
|
|
|
{ RUN_STATE_IO_ERROR, RUN_STATE_FINISH_MIGRATE },
|
2016-02-13 16:26:26 +03:00
|
|
|
{ RUN_STATE_IO_ERROR, RUN_STATE_PRELAUNCH },
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_PAUSED, RUN_STATE_RUNNING },
|
2011-10-14 18:18:09 +04:00
|
|
|
{ RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
|
2017-08-04 20:50:11 +03:00
|
|
|
{ RUN_STATE_PAUSED, RUN_STATE_POSTMIGRATE },
|
2016-02-13 16:26:26 +03:00
|
|
|
{ RUN_STATE_PAUSED, RUN_STATE_PRELAUNCH },
|
2016-10-27 09:42:58 +03:00
|
|
|
{ RUN_STATE_PAUSED, RUN_STATE_COLO},
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
|
2011-10-14 18:18:09 +04:00
|
|
|
{ RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
|
2016-02-13 16:26:26 +03:00
|
|
|
{ RUN_STATE_POSTMIGRATE, RUN_STATE_PRELAUNCH },
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },
|
2011-10-14 18:18:09 +04:00
|
|
|
{ RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE },
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
|
2017-08-04 20:50:11 +03:00
|
|
|
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED },
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
|
2016-02-13 16:26:26 +03:00
|
|
|
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_PRELAUNCH },
|
2016-10-27 09:42:58 +03:00
|
|
|
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO},
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING },
|
2016-02-13 16:26:26 +03:00
|
|
|
{ RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH },
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2016-10-27 09:42:58 +03:00
|
|
|
{ RUN_STATE_COLO, RUN_STATE_RUNNING },
|
|
|
|
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_DEBUG },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_IO_ERROR },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_PAUSED },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_FINISH_MIGRATE },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_RESTORE_VM },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_SAVE_VM },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
|
2013-04-26 07:24:40 +04:00
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
|
2016-10-27 09:42:58 +03:00
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_COLO},
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
|
2011-10-14 18:18:09 +04:00
|
|
|
{ RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
|
2016-02-13 16:26:26 +03:00
|
|
|
{ RUN_STATE_SHUTDOWN, RUN_STATE_PRELAUNCH },
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2012-04-27 20:33:36 +04:00
|
|
|
{ RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
|
|
|
|
{ RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
|
|
|
|
{ RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
|
2016-02-13 16:26:26 +03:00
|
|
|
{ RUN_STATE_SUSPENDED, RUN_STATE_PRELAUNCH },
|
2016-10-27 09:42:58 +03:00
|
|
|
{ RUN_STATE_SUSPENDED, RUN_STATE_COLO},
|
2012-04-27 20:33:36 +04:00
|
|
|
|
2011-09-30 21:45:27 +04:00
|
|
|
{ RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
|
2011-10-14 18:18:09 +04:00
|
|
|
{ RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
|
2016-02-13 16:26:26 +03:00
|
|
|
{ RUN_STATE_WATCHDOG, RUN_STATE_PRELAUNCH },
|
2016-10-27 09:42:58 +03:00
|
|
|
{ RUN_STATE_WATCHDOG, RUN_STATE_COLO},
|
2011-09-05 23:36:31 +04:00
|
|
|
|
vl: allow "cont" from panicked state
After reporting the GUEST_PANICKED monitor event, QEMU stops the VM.
The reason for this is that events are edge-triggered, and can be lost if
management dies at the wrong time. Stopping a panicked VM lets management
know of a panic even if it has crashed; management can learn about the
panic when it restarts and queries running QEMU processes. The downside
is of course that the VM will be paused while management is not running,
but that is acceptable if it only happens with explicit "-device pvpanic".
Upon learning of a panic, management (if configured to do so) can pick a
variety of behaviors: leave the VM paused, reset it, destroy it. In
addition to all of these behaviors, it is possible to dump the VM core
from the host.
However, right now, the panicked state is irreversible, and can only be
exited by resetting the machine. This means that any policy decision
is entirely in the hands of the host. In particular there is no way to
use the "reboot on panic" option together with pvpanic.
This patch makes the panicked state reversible (and removes various
workarounds that were there because of the state being irreversible).
With this change, management has a wider set of possible policies: it
can just log the crash and leave policy to the guest, it can leave the
VM paused. In particular, the "log the crash and continue" is implemented
simply by sending a "cont" as soon as management learns about the panic.
Management could also implement the "irreversible paused state" itself.
And again, all such actions can be coupled with dumping the VM core.
Unfortunately we cannot change the behavior of 1.6.0. Thus, even if
it uses "-device pvpanic", management should check for "cont" failures.
If "cont" fails, management can then log that the VM remained paused
and urge the administrator to update QEMU.
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2013-11-04 17:30:47 +04:00
|
|
|
{ RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING },
|
2013-05-20 14:46:20 +04:00
|
|
|
{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
|
2016-02-13 16:26:26 +03:00
|
|
|
{ RUN_STATE_GUEST_PANICKED, RUN_STATE_PRELAUNCH },
|
2013-04-26 07:24:40 +04:00
|
|
|
|
qapi: Don't let implicit enum MAX member collide
Now that we guarantee the user doesn't have any enum values
beginning with a single underscore, we can use that for our
own purposes. Renaming ENUM_MAX to ENUM__MAX makes it obvious
that the sentinel is generated.
This patch was mostly generated by applying a temporary patch:
|diff --git a/scripts/qapi.py b/scripts/qapi.py
|index e6d014b..b862ec9 100644
|--- a/scripts/qapi.py
|+++ b/scripts/qapi.py
|@@ -1570,6 +1570,7 @@ const char *const %(c_name)s_lookup[] = {
| max_index = c_enum_const(name, 'MAX', prefix)
| ret += mcgen('''
| [%(max_index)s] = NULL,
|+// %(max_index)s
| };
| ''',
| max_index=max_index)
then running:
$ cat qapi-{types,event}.c tests/test-qapi-types.c |
sed -n 's,^// \(.*\)MAX,s|\1MAX|\1_MAX|g,p' > list
$ git grep -l _MAX | xargs sed -i -f list
The only things not generated are the changes in scripts/qapi.py.
Rejecting enum members named 'MAX' is now useless, and will be dropped
in the next patch.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1447836791-369-23-git-send-email-eblake@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
[Rebased to current master, commit message tweaked]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-11-18 11:52:57 +03:00
|
|
|
{ RUN_STATE__MAX, RUN_STATE__MAX },
|
2011-09-05 23:36:31 +04:00
|
|
|
};
|
|
|
|
|
qapi: Don't let implicit enum MAX member collide
Now that we guarantee the user doesn't have any enum values
beginning with a single underscore, we can use that for our
own purposes. Renaming ENUM_MAX to ENUM__MAX makes it obvious
that the sentinel is generated.
This patch was mostly generated by applying a temporary patch:
|diff --git a/scripts/qapi.py b/scripts/qapi.py
|index e6d014b..b862ec9 100644
|--- a/scripts/qapi.py
|+++ b/scripts/qapi.py
|@@ -1570,6 +1570,7 @@ const char *const %(c_name)s_lookup[] = {
| max_index = c_enum_const(name, 'MAX', prefix)
| ret += mcgen('''
| [%(max_index)s] = NULL,
|+// %(max_index)s
| };
| ''',
| max_index=max_index)
then running:
$ cat qapi-{types,event}.c tests/test-qapi-types.c |
sed -n 's,^// \(.*\)MAX,s|\1MAX|\1_MAX|g,p' > list
$ git grep -l _MAX | xargs sed -i -f list
The only things not generated are the changes in scripts/qapi.py.
Rejecting enum members named 'MAX' is now useless, and will be dropped
in the next patch.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1447836791-369-23-git-send-email-eblake@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
[Rebased to current master, commit message tweaked]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-11-18 11:52:57 +03:00
|
|
|
static bool runstate_valid_transitions[RUN_STATE__MAX][RUN_STATE__MAX];
|
2011-09-30 21:45:27 +04:00
|
|
|
|
2011-07-29 22:04:45 +04:00
|
|
|
bool runstate_check(RunState state)
|
|
|
|
{
|
|
|
|
return current_run_state == state;
|
|
|
|
}
|
|
|
|
|
2014-10-08 13:53:22 +04:00
|
|
|
bool runstate_store(char *str, size_t size)
|
|
|
|
{
|
2017-08-24 11:46:08 +03:00
|
|
|
const char *state = RunState_str(current_run_state);
|
2014-10-08 13:53:22 +04:00
|
|
|
size_t len = strlen(state) + 1;
|
|
|
|
|
|
|
|
if (len > size) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
memcpy(str, state, len);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-10-28 15:04:47 +04:00
|
|
|
static void runstate_init(void)
|
2011-09-05 23:36:31 +04:00
|
|
|
{
|
|
|
|
const RunStateTransition *p;
|
|
|
|
|
|
|
|
memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions));
|
qapi: Don't let implicit enum MAX member collide
Now that we guarantee the user doesn't have any enum values
beginning with a single underscore, we can use that for our
own purposes. Renaming ENUM_MAX to ENUM__MAX makes it obvious
that the sentinel is generated.
This patch was mostly generated by applying a temporary patch:
|diff --git a/scripts/qapi.py b/scripts/qapi.py
|index e6d014b..b862ec9 100644
|--- a/scripts/qapi.py
|+++ b/scripts/qapi.py
|@@ -1570,6 +1570,7 @@ const char *const %(c_name)s_lookup[] = {
| max_index = c_enum_const(name, 'MAX', prefix)
| ret += mcgen('''
| [%(max_index)s] = NULL,
|+// %(max_index)s
| };
| ''',
| max_index=max_index)
then running:
$ cat qapi-{types,event}.c tests/test-qapi-types.c |
sed -n 's,^// \(.*\)MAX,s|\1MAX|\1_MAX|g,p' > list
$ git grep -l _MAX | xargs sed -i -f list
The only things not generated are the changes in scripts/qapi.py.
Rejecting enum members named 'MAX' is now useless, and will be dropped
in the next patch.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1447836791-369-23-git-send-email-eblake@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
[Rebased to current master, commit message tweaked]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-11-18 11:52:57 +03:00
|
|
|
for (p = &runstate_transitions_def[0]; p->from != RUN_STATE__MAX; p++) {
|
2011-09-05 23:36:31 +04:00
|
|
|
runstate_valid_transitions[p->from][p->to] = true;
|
|
|
|
}
|
2014-06-05 16:53:58 +04:00
|
|
|
|
|
|
|
qemu_mutex_init(&vmstop_lock);
|
2011-09-05 23:36:31 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* This function will abort() on invalid state transitions */
|
2011-07-29 22:04:45 +04:00
|
|
|
void runstate_set(RunState new_state)
|
|
|
|
{
|
qapi: Don't let implicit enum MAX member collide
Now that we guarantee the user doesn't have any enum values
beginning with a single underscore, we can use that for our
own purposes. Renaming ENUM_MAX to ENUM__MAX makes it obvious
that the sentinel is generated.
This patch was mostly generated by applying a temporary patch:
|diff --git a/scripts/qapi.py b/scripts/qapi.py
|index e6d014b..b862ec9 100644
|--- a/scripts/qapi.py
|+++ b/scripts/qapi.py
|@@ -1570,6 +1570,7 @@ const char *const %(c_name)s_lookup[] = {
| max_index = c_enum_const(name, 'MAX', prefix)
| ret += mcgen('''
| [%(max_index)s] = NULL,
|+// %(max_index)s
| };
| ''',
| max_index=max_index)
then running:
$ cat qapi-{types,event}.c tests/test-qapi-types.c |
sed -n 's,^// \(.*\)MAX,s|\1MAX|\1_MAX|g,p' > list
$ git grep -l _MAX | xargs sed -i -f list
The only things not generated are the changes in scripts/qapi.py.
Rejecting enum members named 'MAX' is now useless, and will be dropped
in the next patch.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1447836791-369-23-git-send-email-eblake@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
[Rebased to current master, commit message tweaked]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-11-18 11:52:57 +03:00
|
|
|
assert(new_state < RUN_STATE__MAX);
|
2011-10-13 17:59:07 +04:00
|
|
|
|
2019-01-24 15:51:54 +03:00
|
|
|
trace_runstate_set(current_run_state, RunState_str(current_run_state),
|
2019-04-26 13:21:15 +03:00
|
|
|
new_state, RunState_str(new_state));
|
2019-01-24 15:51:54 +03:00
|
|
|
|
2016-04-14 06:25:52 +03:00
|
|
|
if (current_run_state == new_state) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-10-13 17:59:07 +04:00
|
|
|
if (!runstate_valid_transitions[current_run_state][new_state]) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("invalid runstate transition: '%s' -> '%s'",
|
2017-08-24 11:46:08 +03:00
|
|
|
RunState_str(current_run_state),
|
|
|
|
RunState_str(new_state));
|
2011-09-05 23:36:31 +04:00
|
|
|
abort();
|
|
|
|
}
|
2019-01-24 15:51:54 +03:00
|
|
|
|
2011-07-29 22:04:45 +04:00
|
|
|
current_run_state = new_state;
|
|
|
|
}
|
|
|
|
|
2011-09-13 00:54:20 +04:00
|
|
|
int runstate_is_running(void)
|
2011-08-29 23:02:57 +04:00
|
|
|
{
|
2011-09-13 00:54:20 +04:00
|
|
|
return runstate_check(RUN_STATE_RUNNING);
|
2011-08-29 23:02:57 +04:00
|
|
|
}
|
|
|
|
|
2013-04-26 07:24:40 +04:00
|
|
|
bool runstate_needs_reset(void)
|
|
|
|
{
|
|
|
|
return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
|
vl: allow "cont" from panicked state
After reporting the GUEST_PANICKED monitor event, QEMU stops the VM.
The reason for this is that events are edge-triggered, and can be lost if
management dies at the wrong time. Stopping a panicked VM lets management
know of a panic even if it has crashed; management can learn about the
panic when it restarts and queries running QEMU processes. The downside
is of course that the VM will be paused while management is not running,
but that is acceptable if it only happens with explicit "-device pvpanic".
Upon learning of a panic, management (if configured to do so) can pick a
variety of behaviors: leave the VM paused, reset it, destroy it. In
addition to all of these behaviors, it is possible to dump the VM core
from the host.
However, right now, the panicked state is irreversible, and can only be
exited by resetting the machine. This means that any policy decision
is entirely in the hands of the host. In particular there is no way to
use the "reboot on panic" option together with pvpanic.
This patch makes the panicked state reversible (and removes various
workarounds that were there because of the state being irreversible).
With this change, management has a wider set of possible policies: it
can just log the crash and leave policy to the guest, it can leave the
VM paused. In particular, the "log the crash and continue" is implemented
simply by sending a "cont" as soon as management learns about the panic.
Management could also implement the "irreversible paused state" itself.
And again, all such actions can be coupled with dumping the VM core.
Unfortunately we cannot change the behavior of 1.6.0. Thus, even if
it uses "-device pvpanic", management should check for "cont" failures.
If "cont" fails, management can then log that the VM remained paused
and urge the administrator to update QEMU.
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2013-11-04 17:30:47 +04:00
|
|
|
runstate_check(RUN_STATE_SHUTDOWN);
|
2013-04-26 07:24:40 +04:00
|
|
|
}
|
|
|
|
|
2011-09-13 00:54:20 +04:00
|
|
|
StatusInfo *qmp_query_status(Error **errp)
|
2011-07-29 22:36:43 +04:00
|
|
|
{
|
2011-09-13 00:54:20 +04:00
|
|
|
StatusInfo *info = g_malloc0(sizeof(*info));
|
|
|
|
|
|
|
|
info->running = runstate_is_running();
|
|
|
|
info->singlestep = singlestep;
|
|
|
|
info->status = current_run_state;
|
|
|
|
|
|
|
|
return info;
|
2011-07-29 22:36:43 +04:00
|
|
|
}
|
|
|
|
|
2017-02-14 20:07:47 +03:00
|
|
|
bool qemu_vmstop_requested(RunState *r)
|
2014-06-05 16:53:58 +04:00
|
|
|
{
|
|
|
|
qemu_mutex_lock(&vmstop_lock);
|
|
|
|
*r = vmstop_requested;
|
qapi: Don't let implicit enum MAX member collide
Now that we guarantee the user doesn't have any enum values
beginning with a single underscore, we can use that for our
own purposes. Renaming ENUM_MAX to ENUM__MAX makes it obvious
that the sentinel is generated.
This patch was mostly generated by applying a temporary patch:
|diff --git a/scripts/qapi.py b/scripts/qapi.py
|index e6d014b..b862ec9 100644
|--- a/scripts/qapi.py
|+++ b/scripts/qapi.py
|@@ -1570,6 +1570,7 @@ const char *const %(c_name)s_lookup[] = {
| max_index = c_enum_const(name, 'MAX', prefix)
| ret += mcgen('''
| [%(max_index)s] = NULL,
|+// %(max_index)s
| };
| ''',
| max_index=max_index)
then running:
$ cat qapi-{types,event}.c tests/test-qapi-types.c |
sed -n 's,^// \(.*\)MAX,s|\1MAX|\1_MAX|g,p' > list
$ git grep -l _MAX | xargs sed -i -f list
The only things not generated are the changes in scripts/qapi.py.
Rejecting enum members named 'MAX' is now useless, and will be dropped
in the next patch.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1447836791-369-23-git-send-email-eblake@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
[Rebased to current master, commit message tweaked]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-11-18 11:52:57 +03:00
|
|
|
vmstop_requested = RUN_STATE__MAX;
|
2014-06-05 16:53:58 +04:00
|
|
|
qemu_mutex_unlock(&vmstop_lock);
|
qapi: Don't let implicit enum MAX member collide
Now that we guarantee the user doesn't have any enum values
beginning with a single underscore, we can use that for our
own purposes. Renaming ENUM_MAX to ENUM__MAX makes it obvious
that the sentinel is generated.
This patch was mostly generated by applying a temporary patch:
|diff --git a/scripts/qapi.py b/scripts/qapi.py
|index e6d014b..b862ec9 100644
|--- a/scripts/qapi.py
|+++ b/scripts/qapi.py
|@@ -1570,6 +1570,7 @@ const char *const %(c_name)s_lookup[] = {
| max_index = c_enum_const(name, 'MAX', prefix)
| ret += mcgen('''
| [%(max_index)s] = NULL,
|+// %(max_index)s
| };
| ''',
| max_index=max_index)
then running:
$ cat qapi-{types,event}.c tests/test-qapi-types.c |
sed -n 's,^// \(.*\)MAX,s|\1MAX|\1_MAX|g,p' > list
$ git grep -l _MAX | xargs sed -i -f list
The only things not generated are the changes in scripts/qapi.py.
Rejecting enum members named 'MAX' is now useless, and will be dropped
in the next patch.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1447836791-369-23-git-send-email-eblake@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
[Rebased to current master, commit message tweaked]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-11-18 11:52:57 +03:00
|
|
|
return *r < RUN_STATE__MAX;
|
2014-06-05 16:53:58 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_system_vmstop_request_prepare(void)
|
|
|
|
{
|
|
|
|
qemu_mutex_lock(&vmstop_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_system_vmstop_request(RunState state)
|
|
|
|
{
|
|
|
|
vmstop_requested = state;
|
|
|
|
qemu_mutex_unlock(&vmstop_lock);
|
|
|
|
qemu_notify_event();
|
|
|
|
}
|
|
|
|
|
2010-01-13 16:05:34 +03:00
|
|
|
/***********************************************************/
|
2018-10-18 10:12:54 +03:00
|
|
|
/* RTC reference time/date access */
|
2018-10-18 10:12:55 +03:00
|
|
|
static time_t qemu_ref_timedate(QEMUClockType clock)
|
2018-10-18 10:12:54 +03:00
|
|
|
{
|
2018-10-18 10:12:55 +03:00
|
|
|
time_t value = qemu_clock_get_ms(clock) / 1000;
|
|
|
|
switch (clock) {
|
2018-10-18 10:12:54 +03:00
|
|
|
case QEMU_CLOCK_REALTIME:
|
|
|
|
value -= rtc_realtime_clock_offset;
|
2019-07-19 16:14:24 +03:00
|
|
|
/* fall through */
|
2018-10-18 10:12:54 +03:00
|
|
|
case QEMU_CLOCK_VIRTUAL:
|
|
|
|
value += rtc_ref_start_datetime;
|
|
|
|
break;
|
|
|
|
case QEMU_CLOCK_HOST:
|
|
|
|
if (rtc_base_type == RTC_BASE_DATETIME) {
|
|
|
|
value -= rtc_host_datetime_offset;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
}
|
|
|
|
return value;
|
2015-02-27 16:11:02 +03:00
|
|
|
}
|
|
|
|
|
2008-02-17 14:42:19 +03:00
|
|
|
void qemu_get_timedate(struct tm *tm, int offset)
|
|
|
|
{
|
2018-10-18 10:12:55 +03:00
|
|
|
time_t ti = qemu_ref_timedate(rtc_clock);
|
2008-02-17 14:42:19 +03:00
|
|
|
|
|
|
|
ti += offset;
|
2018-10-18 10:12:53 +03:00
|
|
|
|
|
|
|
switch (rtc_base_type) {
|
2018-10-18 10:12:54 +03:00
|
|
|
case RTC_BASE_DATETIME:
|
2018-10-18 10:12:53 +03:00
|
|
|
case RTC_BASE_UTC:
|
2013-01-08 02:08:13 +04:00
|
|
|
gmtime_r(&ti, tm);
|
2018-10-18 10:12:53 +03:00
|
|
|
break;
|
|
|
|
case RTC_BASE_LOCALTIME:
|
|
|
|
localtime_r(&ti, tm);
|
|
|
|
break;
|
2008-02-17 14:42:19 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int qemu_timedate_diff(struct tm *tm)
|
|
|
|
{
|
|
|
|
time_t seconds;
|
|
|
|
|
2018-10-18 10:12:53 +03:00
|
|
|
switch (rtc_base_type) {
|
2018-10-18 10:12:54 +03:00
|
|
|
case RTC_BASE_DATETIME:
|
2018-10-18 10:12:53 +03:00
|
|
|
case RTC_BASE_UTC:
|
|
|
|
seconds = mktimegm(tm);
|
|
|
|
break;
|
|
|
|
case RTC_BASE_LOCALTIME:
|
|
|
|
{
|
|
|
|
struct tm tmp = *tm;
|
|
|
|
tmp.tm_isdst = -1; /* use timezone to figure it out */
|
|
|
|
seconds = mktime(&tmp);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
}
|
2008-02-17 14:42:19 +03:00
|
|
|
|
2018-10-18 10:12:55 +03:00
|
|
|
return seconds - qemu_ref_timedate(QEMU_CLOCK_HOST);
|
2008-02-17 14:42:19 +03:00
|
|
|
}
|
|
|
|
|
2018-10-18 10:12:54 +03:00
|
|
|
static void configure_rtc_base_datetime(const char *startdate)
|
2009-09-15 15:36:04 +04:00
|
|
|
{
|
2018-10-18 10:12:53 +03:00
|
|
|
time_t rtc_start_datetime;
|
2009-09-15 15:36:04 +04:00
|
|
|
struct tm tm;
|
|
|
|
|
2018-08-21 16:18:06 +03:00
|
|
|
if (sscanf(startdate, "%d-%d-%dT%d:%d:%d", &tm.tm_year, &tm.tm_mon,
|
|
|
|
&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6) {
|
|
|
|
/* OK */
|
|
|
|
} else if (sscanf(startdate, "%d-%d-%d",
|
|
|
|
&tm.tm_year, &tm.tm_mon, &tm.tm_mday) == 3) {
|
|
|
|
tm.tm_hour = 0;
|
|
|
|
tm.tm_min = 0;
|
|
|
|
tm.tm_sec = 0;
|
2009-09-15 15:36:04 +04:00
|
|
|
} else {
|
2018-08-21 16:18:06 +03:00
|
|
|
goto date_fail;
|
|
|
|
}
|
|
|
|
tm.tm_year -= 1900;
|
|
|
|
tm.tm_mon--;
|
2018-10-18 10:12:53 +03:00
|
|
|
rtc_start_datetime = mktimegm(&tm);
|
|
|
|
if (rtc_start_datetime == -1) {
|
2018-08-21 16:18:06 +03:00
|
|
|
date_fail:
|
2018-10-18 10:12:53 +03:00
|
|
|
error_report("invalid datetime format");
|
2018-08-21 16:18:06 +03:00
|
|
|
error_printf("valid formats: "
|
|
|
|
"'2006-06-17T16:01:21' or '2006-06-17'\n");
|
|
|
|
exit(1);
|
2009-09-15 15:36:04 +04:00
|
|
|
}
|
2018-10-18 10:12:54 +03:00
|
|
|
rtc_host_datetime_offset = rtc_ref_start_datetime - rtc_start_datetime;
|
|
|
|
rtc_ref_start_datetime = rtc_start_datetime;
|
2009-09-15 15:36:04 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void configure_rtc(QemuOpts *opts)
|
|
|
|
{
|
|
|
|
const char *value;
|
|
|
|
|
2018-10-18 10:12:54 +03:00
|
|
|
/* Set defaults */
|
|
|
|
rtc_clock = QEMU_CLOCK_HOST;
|
|
|
|
rtc_ref_start_datetime = qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
|
|
|
|
rtc_realtime_clock_offset = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000;
|
|
|
|
|
2009-09-15 15:36:04 +04:00
|
|
|
value = qemu_opt_get(opts, "base");
|
|
|
|
if (value) {
|
|
|
|
if (!strcmp(value, "utc")) {
|
2018-10-18 10:12:53 +03:00
|
|
|
rtc_base_type = RTC_BASE_UTC;
|
2009-09-15 15:36:04 +04:00
|
|
|
} else if (!strcmp(value, "localtime")) {
|
2015-09-17 19:25:13 +03:00
|
|
|
Error *blocker = NULL;
|
2018-10-18 10:12:53 +03:00
|
|
|
rtc_base_type = RTC_BASE_LOCALTIME;
|
2015-09-17 19:25:13 +03:00
|
|
|
error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED,
|
|
|
|
"-rtc base=localtime");
|
|
|
|
replay_add_blocker(blocker);
|
2009-09-15 15:36:04 +04:00
|
|
|
} else {
|
2018-10-18 10:12:53 +03:00
|
|
|
rtc_base_type = RTC_BASE_DATETIME;
|
2018-10-18 10:12:54 +03:00
|
|
|
configure_rtc_base_datetime(value);
|
2009-09-15 15:36:04 +04:00
|
|
|
}
|
|
|
|
}
|
2009-09-15 15:36:04 +04:00
|
|
|
value = qemu_opt_get(opts, "clock");
|
|
|
|
if (value) {
|
|
|
|
if (!strcmp(value, "host")) {
|
2013-08-21 19:03:04 +04:00
|
|
|
rtc_clock = QEMU_CLOCK_HOST;
|
2012-03-30 14:31:21 +04:00
|
|
|
} else if (!strcmp(value, "rt")) {
|
2013-08-21 19:03:04 +04:00
|
|
|
rtc_clock = QEMU_CLOCK_REALTIME;
|
2009-09-15 15:36:04 +04:00
|
|
|
} else if (!strcmp(value, "vm")) {
|
2013-08-21 19:03:04 +04:00
|
|
|
rtc_clock = QEMU_CLOCK_VIRTUAL;
|
2009-09-15 15:36:04 +04:00
|
|
|
} else {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("invalid option value '%s'", value);
|
2009-09-15 15:36:04 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
2009-09-15 15:36:04 +04:00
|
|
|
value = qemu_opt_get(opts, "driftfix");
|
|
|
|
if (value) {
|
2010-03-28 00:33:46 +03:00
|
|
|
if (!strcmp(value, "slew")) {
|
2019-11-13 15:33:44 +03:00
|
|
|
object_register_sugar_prop("mc146818rtc",
|
|
|
|
"lost_tick_policy",
|
|
|
|
"slew");
|
2010-03-28 00:33:46 +03:00
|
|
|
} else if (!strcmp(value, "none")) {
|
2012-01-23 23:15:12 +04:00
|
|
|
/* discard is default */
|
2009-09-15 15:36:04 +04:00
|
|
|
} else {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("invalid option value '%s'", value);
|
2009-09-15 15:36:04 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-13 15:35:14 +03:00
|
|
|
static int parse_name(void *opaque, QemuOpts *opts, Error **errp)
|
2014-01-30 14:20:30 +04:00
|
|
|
{
|
|
|
|
const char *proc_name;
|
|
|
|
|
2014-01-30 14:20:31 +04:00
|
|
|
if (qemu_opt_get(opts, "debug-threads")) {
|
|
|
|
qemu_thread_naming(qemu_opt_get_bool(opts, "debug-threads", false));
|
|
|
|
}
|
2014-01-30 14:20:30 +04:00
|
|
|
qemu_name = qemu_opt_get(opts, "guest");
|
|
|
|
|
|
|
|
proc_name = qemu_opt_get(opts, "process");
|
|
|
|
if (proc_name) {
|
|
|
|
os_set_proc_name(proc_name);
|
|
|
|
}
|
2014-05-06 15:15:55 +04:00
|
|
|
|
|
|
|
return 0;
|
2014-01-30 14:20:30 +04:00
|
|
|
}
|
|
|
|
|
2015-01-06 16:29:12 +03:00
|
|
|
bool defaults_enabled(void)
|
|
|
|
{
|
|
|
|
return has_defaults;
|
|
|
|
}
|
|
|
|
|
2012-10-18 23:19:34 +04:00
|
|
|
#ifndef _WIN32
|
2015-03-13 15:35:14 +03:00
|
|
|
static int parse_add_fd(void *opaque, QemuOpts *opts, Error **errp)
|
2012-10-18 23:19:34 +04:00
|
|
|
{
|
|
|
|
int fd, dupfd, flags;
|
|
|
|
int64_t fdset_id;
|
|
|
|
const char *fd_opaque = NULL;
|
2015-03-15 12:16:28 +03:00
|
|
|
AddfdInfo *fdinfo;
|
2012-10-18 23:19:34 +04:00
|
|
|
|
|
|
|
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) {
|
2018-10-17 11:26:42 +03:00
|
|
|
error_setg(errp, "fd option is required and must be non-negative");
|
2012-10-18 23:19:34 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fd <= STDERR_FILENO) {
|
2018-10-17 11:26:42 +03:00
|
|
|
error_setg(errp, "fd cannot be a standard I/O stream");
|
2012-10-18 23:19:34 +04:00
|
|
|
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)) {
|
2018-10-17 11:26:42 +03:00
|
|
|
error_setg(errp, "fd is not valid or already in use");
|
2012-10-18 23:19:34 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fdset_id < 0) {
|
2018-10-17 11:26:42 +03:00
|
|
|
error_setg(errp, "set option is required and must be non-negative");
|
2012-10-18 23:19:34 +04:00
|
|
|
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) {
|
2018-10-17 11:26:42 +03:00
|
|
|
error_setg(errp, "error duplicating fd: %s", strerror(errno));
|
2012-10-18 23:19:34 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add the duplicate fd, and optionally the opaque string, to the fd set */
|
2015-03-15 12:16:28 +03:00
|
|
|
fdinfo = monitor_fdset_add_fd(dupfd, true, fdset_id, !!fd_opaque, fd_opaque,
|
|
|
|
&error_abort);
|
|
|
|
g_free(fdinfo);
|
2012-10-18 23:19:34 +04:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-13 15:35:14 +03:00
|
|
|
static int cleanup_add_fd(void *opaque, QemuOpts *opts, Error **errp)
|
2012-10-18 23:19:34 +04:00
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
fd = qemu_opt_get_number(opts, "fd", -1);
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-09-29 03:19:47 +04:00
|
|
|
/***********************************************************/
|
|
|
|
/* QEMU Block devices */
|
|
|
|
|
2011-01-28 13:21:41 +03:00
|
|
|
#define HD_OPTS "media=disk"
|
|
|
|
#define CDROM_OPTS "media=cdrom"
|
|
|
|
#define FD_OPTS ""
|
|
|
|
#define PFLASH_OPTS ""
|
|
|
|
#define MTD_OPTS ""
|
|
|
|
#define SD_OPTS ""
|
2007-12-02 07:51:10 +03:00
|
|
|
|
2015-03-13 15:35:14 +03:00
|
|
|
static int drive_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
2009-07-22 18:43:04 +04:00
|
|
|
{
|
2012-11-20 18:30:34 +04:00
|
|
|
BlockInterfaceType *block_default_type = opaque;
|
2009-07-22 18:43:04 +04:00
|
|
|
|
2018-10-17 11:26:57 +03:00
|
|
|
return drive_new(opts, *block_default_type, errp) == NULL;
|
2009-07-22 18:43:04 +04:00
|
|
|
}
|
|
|
|
|
2015-03-13 15:35:14 +03:00
|
|
|
static int drive_enable_snapshot(void *opaque, QemuOpts *opts, Error **errp)
|
2009-07-22 18:43:04 +04:00
|
|
|
{
|
2014-08-11 17:00:57 +04:00
|
|
|
if (qemu_opt_get(opts, "snapshot") == NULL) {
|
2015-02-12 19:52:20 +03:00
|
|
|
qemu_opt_set(opts, "snapshot", "on", &error_abort);
|
2009-07-22 18:43:04 +04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-11-23 00:02:55 +04:00
|
|
|
static void default_drive(int enable, int snapshot, BlockInterfaceType type,
|
|
|
|
int index, const char *optstr)
|
blockdev: Reject multiple definitions for the same drive
We silently ignore multiple definitions for the same drive:
$ qemu-system-x86_64 -nodefaults -vnc :1 -S -monitor stdio -drive if=ide,index=1,file=tmp.qcow2 -drive if=ide,index=1,file=nonexistant
QEMU 0.13.50 monitor - type 'help' for more information
(qemu) info block
ide0-hd1: type=hd removable=0 file=tmp.qcow2 backing_file=tmp.img ro=0 drv=qcow2 encrypted=0
With if=none, this can become quite confusing:
$ qemu-system-x86_64 -nodefaults -vnc :1 -S -monitor stdio -drive if=none,index=1,file=tmp.qcow2,id=eins -drive if=none,index=1,file=nonexistant,id=zwei -device ide-drive,drive=eins -device ide-drive,drive=zwei
qemu-system-x86_64: -device ide-drive,drive=zwei: Property 'ide-drive.drive' can't find value 'zwei'
The second -device fails, because it refers to drive zwei, which got
silently ignored.
Make multiple drive definitions fail cleanly.
Unfortunately, there's code that relies on multiple drive definitions
being silently ignored: main() merrily adds default drives even when
the user already defined these drives. Fix that up.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-01-28 13:21:45 +03:00
|
|
|
{
|
|
|
|
QemuOpts *opts;
|
2014-10-01 22:19:24 +04:00
|
|
|
DriveInfo *dinfo;
|
blockdev: Reject multiple definitions for the same drive
We silently ignore multiple definitions for the same drive:
$ qemu-system-x86_64 -nodefaults -vnc :1 -S -monitor stdio -drive if=ide,index=1,file=tmp.qcow2 -drive if=ide,index=1,file=nonexistant
QEMU 0.13.50 monitor - type 'help' for more information
(qemu) info block
ide0-hd1: type=hd removable=0 file=tmp.qcow2 backing_file=tmp.img ro=0 drv=qcow2 encrypted=0
With if=none, this can become quite confusing:
$ qemu-system-x86_64 -nodefaults -vnc :1 -S -monitor stdio -drive if=none,index=1,file=tmp.qcow2,id=eins -drive if=none,index=1,file=nonexistant,id=zwei -device ide-drive,drive=eins -device ide-drive,drive=zwei
qemu-system-x86_64: -device ide-drive,drive=zwei: Property 'ide-drive.drive' can't find value 'zwei'
The second -device fails, because it refers to drive zwei, which got
silently ignored.
Make multiple drive definitions fail cleanly.
Unfortunately, there's code that relies on multiple drive definitions
being silently ignored: main() merrily adds default drives even when
the user already defined these drives. Fix that up.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-01-28 13:21:45 +03:00
|
|
|
|
|
|
|
if (!enable || drive_get_by_index(type, index)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
opts = drive_add(type, index, NULL, optstr);
|
|
|
|
if (snapshot) {
|
2015-03-13 15:35:14 +03:00
|
|
|
drive_enable_snapshot(NULL, opts, NULL);
|
blockdev: Reject multiple definitions for the same drive
We silently ignore multiple definitions for the same drive:
$ qemu-system-x86_64 -nodefaults -vnc :1 -S -monitor stdio -drive if=ide,index=1,file=tmp.qcow2 -drive if=ide,index=1,file=nonexistant
QEMU 0.13.50 monitor - type 'help' for more information
(qemu) info block
ide0-hd1: type=hd removable=0 file=tmp.qcow2 backing_file=tmp.img ro=0 drv=qcow2 encrypted=0
With if=none, this can become quite confusing:
$ qemu-system-x86_64 -nodefaults -vnc :1 -S -monitor stdio -drive if=none,index=1,file=tmp.qcow2,id=eins -drive if=none,index=1,file=nonexistant,id=zwei -device ide-drive,drive=eins -device ide-drive,drive=zwei
qemu-system-x86_64: -device ide-drive,drive=zwei: Property 'ide-drive.drive' can't find value 'zwei'
The second -device fails, because it refers to drive zwei, which got
silently ignored.
Make multiple drive definitions fail cleanly.
Unfortunately, there's code that relies on multiple drive definitions
being silently ignored: main() merrily adds default drives even when
the user already defined these drives. Fix that up.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-01-28 13:21:45 +03:00
|
|
|
}
|
2014-10-01 22:19:24 +04:00
|
|
|
|
2018-10-17 11:26:57 +03:00
|
|
|
dinfo = drive_new(opts, type, &error_abort);
|
2014-10-01 22:19:24 +04:00
|
|
|
dinfo->is_default = true;
|
|
|
|
|
blockdev: Reject multiple definitions for the same drive
We silently ignore multiple definitions for the same drive:
$ qemu-system-x86_64 -nodefaults -vnc :1 -S -monitor stdio -drive if=ide,index=1,file=tmp.qcow2 -drive if=ide,index=1,file=nonexistant
QEMU 0.13.50 monitor - type 'help' for more information
(qemu) info block
ide0-hd1: type=hd removable=0 file=tmp.qcow2 backing_file=tmp.img ro=0 drv=qcow2 encrypted=0
With if=none, this can become quite confusing:
$ qemu-system-x86_64 -nodefaults -vnc :1 -S -monitor stdio -drive if=none,index=1,file=tmp.qcow2,id=eins -drive if=none,index=1,file=nonexistant,id=zwei -device ide-drive,drive=eins -device ide-drive,drive=zwei
qemu-system-x86_64: -device ide-drive,drive=zwei: Property 'ide-drive.drive' can't find value 'zwei'
The second -device fails, because it refers to drive zwei, which got
silently ignored.
Make multiple drive definitions fail cleanly.
Unfortunately, there's code that relies on multiple drive definitions
being silently ignored: main() merrily adds default drives even when
the user already defined these drives. Fix that up.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-01-28 13:21:45 +03:00
|
|
|
}
|
|
|
|
|
2019-03-08 16:14:38 +03:00
|
|
|
typedef struct BlockdevOptionsQueueEntry {
|
|
|
|
BlockdevOptions *bdo;
|
|
|
|
Location loc;
|
|
|
|
QSIMPLEQ_ENTRY(BlockdevOptionsQueueEntry) entry;
|
|
|
|
} BlockdevOptionsQueueEntry;
|
|
|
|
|
|
|
|
typedef QSIMPLEQ_HEAD(, BlockdevOptionsQueueEntry) BlockdevOptionsQueue;
|
|
|
|
|
2019-03-08 16:14:39 +03:00
|
|
|
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);
|
|
|
|
}
|
2019-09-17 14:57:56 +03:00
|
|
|
if (snapshot) {
|
2019-03-08 16:14:39 +03:00
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
vl: convert -smp to qemu_opts_parse()
This also introduces a new suboption, "cpus=",
which is the default. So after this patch,
-smp n,sockets=y
is the same as
-smp cpus=n,sockets=y
(with "cpu" being some generic thing, referring to
either cores, or threads, or sockets, as before).
We still don't validate relations between different
numbers, for example it is still possible to say
-smp 1,sockets=10
and it will be accepted to mean sockets=1.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Message-id: 1372072012-30305-1-git-send-email-mjt@msgid.tls.msk.ru
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-24 15:06:52 +04:00
|
|
|
static QemuOptsList qemu_smp_opts = {
|
|
|
|
.name = "smp-opts",
|
|
|
|
.implied_opt_name = "cpus",
|
|
|
|
.merge_lists = true,
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_smp_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "cpus",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
}, {
|
|
|
|
.name = "sockets",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
2019-06-20 08:45:25 +03:00
|
|
|
}, {
|
|
|
|
.name = "dies",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
vl: convert -smp to qemu_opts_parse()
This also introduces a new suboption, "cpus=",
which is the default. So after this patch,
-smp n,sockets=y
is the same as
-smp cpus=n,sockets=y
(with "cpu" being some generic thing, referring to
either cores, or threads, or sockets, as before).
We still don't validate relations between different
numbers, for example it is still possible to say
-smp 1,sockets=10
and it will be accepted to mean sockets=1.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Message-id: 1372072012-30305-1-git-send-email-mjt@msgid.tls.msk.ru
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-24 15:06:52 +04:00
|
|
|
}, {
|
|
|
|
.name = "cores",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
}, {
|
|
|
|
.name = "threads",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
}, {
|
|
|
|
.name = "maxcpus",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
},
|
|
|
|
{ /*End of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2014-09-23 14:42:24 +04:00
|
|
|
static void realtime_init(void)
|
2013-04-19 18:42:06 +04:00
|
|
|
{
|
|
|
|
if (enable_mlock) {
|
|
|
|
if (os_mlock() < 0) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("locking memory failed");
|
2013-04-19 18:42:06 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-04 07:02:46 +04:00
|
|
|
|
|
|
|
static void configure_msg(QemuOpts *opts)
|
|
|
|
{
|
2019-10-10 11:15:08 +03:00
|
|
|
error_with_timestamp = qemu_opt_get_bool(opts, "timestamp", false);
|
2013-07-04 07:02:46 +04:00
|
|
|
}
|
|
|
|
|
2015-06-19 16:17:45 +03:00
|
|
|
|
2005-11-06 19:13:29 +03:00
|
|
|
/***********************************************************/
|
|
|
|
/* USB devices */
|
|
|
|
|
2010-05-28 17:38:44 +04:00
|
|
|
static int usb_device_add(const char *devname)
|
2005-11-06 19:13:29 +03:00
|
|
|
{
|
2009-08-31 16:24:00 +04:00
|
|
|
USBDevice *dev = NULL;
|
2005-11-06 19:13:29 +03:00
|
|
|
|
2016-06-08 23:50:25 +03:00
|
|
|
if (!machine_usb(current_machine)) {
|
2005-11-06 19:13:29 +03:00
|
|
|
return -1;
|
2012-09-02 23:25:28 +04:00
|
|
|
}
|
2005-11-06 19:13:29 +03:00
|
|
|
|
2009-10-26 17:56:45 +03:00
|
|
|
dev = usbdevice_create(devname);
|
2006-05-21 20:30:15 +04:00
|
|
|
if (!dev)
|
|
|
|
return -1;
|
|
|
|
|
2005-11-06 19:13:29 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-07-15 15:59:26 +04:00
|
|
|
static int usb_parse(const char *cmdline)
|
|
|
|
{
|
2009-12-22 23:30:18 +03:00
|
|
|
int r;
|
2010-05-28 17:38:44 +04:00
|
|
|
r = usb_device_add(cmdline);
|
2009-12-22 23:30:18 +03:00
|
|
|
if (r < 0) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("could not add USB device '%s'", cmdline);
|
2009-12-22 23:30:18 +03:00
|
|
|
}
|
|
|
|
return r;
|
2009-07-15 15:59:26 +04:00
|
|
|
}
|
|
|
|
|
2005-06-05 18:49:17 +04:00
|
|
|
/***********************************************************/
|
|
|
|
/* machine registration */
|
|
|
|
|
2014-03-05 21:30:47 +04:00
|
|
|
MachineState *current_machine;
|
2005-06-05 18:49:17 +04:00
|
|
|
|
2019-04-05 09:41:19 +03:00
|
|
|
static MachineClass *find_machine(const char *name, GSList *machines)
|
2005-06-05 18:49:17 +04:00
|
|
|
{
|
2019-04-05 09:41:19 +03:00
|
|
|
GSList *el;
|
2005-06-05 18:49:17 +04:00
|
|
|
|
2014-03-05 21:30:46 +04:00
|
|
|
for (el = machines; el; el = el->next) {
|
2019-04-05 09:41:20 +03:00
|
|
|
MachineClass *mc = el->data;
|
2014-03-05 21:30:46 +04:00
|
|
|
|
2019-04-05 09:41:20 +03:00
|
|
|
if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) {
|
|
|
|
return mc;
|
2014-03-05 21:30:46 +04:00
|
|
|
}
|
2005-06-05 18:49:17 +04:00
|
|
|
}
|
2014-03-05 21:30:46 +04:00
|
|
|
|
2019-04-05 09:41:20 +03:00
|
|
|
return NULL;
|
2005-06-05 18:49:17 +04:00
|
|
|
}
|
|
|
|
|
2019-04-05 09:41:19 +03:00
|
|
|
static MachineClass *find_default_machine(GSList *machines)
|
2009-05-22 05:41:01 +04:00
|
|
|
{
|
2019-04-05 09:41:19 +03:00
|
|
|
GSList *el;
|
2009-05-22 05:41:01 +04:00
|
|
|
|
2014-03-05 21:30:46 +04:00
|
|
|
for (el = machines; el; el = el->next) {
|
2019-04-05 09:41:20 +03:00
|
|
|
MachineClass *mc = el->data;
|
2014-03-05 21:30:46 +04:00
|
|
|
|
2019-04-05 09:41:20 +03:00
|
|
|
if (mc->is_default) {
|
|
|
|
return mc;
|
2009-05-22 05:41:01 +04:00
|
|
|
}
|
|
|
|
}
|
2014-03-05 21:30:46 +04:00
|
|
|
|
2019-04-05 09:41:20 +03:00
|
|
|
return NULL;
|
2009-05-22 05:41:01 +04:00
|
|
|
}
|
|
|
|
|
2014-12-16 19:58:06 +03:00
|
|
|
static int machine_help_func(QemuOpts *opts, MachineState *machine)
|
|
|
|
{
|
|
|
|
ObjectProperty *prop;
|
2015-12-09 15:34:02 +03:00
|
|
|
ObjectPropertyIterator iter;
|
2014-12-16 19:58:06 +03:00
|
|
|
|
|
|
|
if (!qemu_opt_has_help_opt(opts)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-12-09 15:34:02 +03:00
|
|
|
object_property_iter_init(&iter, OBJECT(machine));
|
|
|
|
while ((prop = object_property_iter_next(&iter))) {
|
2014-12-16 19:58:06 +03:00
|
|
|
if (!prop->set) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-04-17 22:06:35 +03:00
|
|
|
printf("%s.%s=%s", MACHINE_GET_CLASS(machine)->name,
|
|
|
|
prop->name, prop->type);
|
2014-12-16 19:58:06 +03:00
|
|
|
if (prop->description) {
|
2019-04-17 22:06:35 +03:00
|
|
|
printf(" (%s)\n", prop->description);
|
2014-12-16 19:58:06 +03:00
|
|
|
} else {
|
2019-04-17 22:06:35 +03:00
|
|
|
printf("\n");
|
2014-12-16 19:58:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2019-08-12 08:23:58 +03:00
|
|
|
struct VMChangeStateEntry {
|
2005-11-11 03:00:47 +03:00
|
|
|
VMChangeStateHandler *cb;
|
|
|
|
void *opaque;
|
2019-08-12 08:23:58 +03:00
|
|
|
QTAILQ_ENTRY(VMChangeStateEntry) entries;
|
2019-06-20 20:37:07 +03:00
|
|
|
int priority;
|
2005-11-11 03:00:47 +03:00
|
|
|
};
|
|
|
|
|
2019-08-12 08:23:58 +03:00
|
|
|
static QTAILQ_HEAD(, VMChangeStateEntry) vm_change_state_head;
|
2005-11-11 03:00:47 +03:00
|
|
|
|
2019-06-20 20:37:07 +03:00
|
|
|
/**
|
|
|
|
* qemu_add_vm_change_state_handler_prio:
|
|
|
|
* @cb: the callback to invoke
|
|
|
|
* @opaque: user data passed to the callback
|
|
|
|
* @priority: low priorities execute first when the vm runs and the reverse is
|
|
|
|
* true when the vm stops
|
|
|
|
*
|
|
|
|
* Register a callback function that is invoked when the vm starts or stops
|
|
|
|
* running.
|
|
|
|
*
|
|
|
|
* Returns: an entry to be freed using qemu_del_vm_change_state_handler()
|
|
|
|
*/
|
|
|
|
VMChangeStateEntry *qemu_add_vm_change_state_handler_prio(
|
|
|
|
VMChangeStateHandler *cb, void *opaque, int priority)
|
2005-11-11 03:00:47 +03:00
|
|
|
{
|
|
|
|
VMChangeStateEntry *e;
|
2019-06-20 20:37:07 +03:00
|
|
|
VMChangeStateEntry *other;
|
2005-11-11 03:00:47 +03:00
|
|
|
|
2019-06-20 20:37:07 +03:00
|
|
|
e = g_malloc0(sizeof(*e));
|
2005-11-11 03:00:47 +03:00
|
|
|
e->cb = cb;
|
|
|
|
e->opaque = opaque;
|
2019-06-20 20:37:07 +03:00
|
|
|
e->priority = priority;
|
|
|
|
|
|
|
|
/* Keep list sorted in ascending priority order */
|
|
|
|
QTAILQ_FOREACH(other, &vm_change_state_head, entries) {
|
|
|
|
if (priority < other->priority) {
|
|
|
|
QTAILQ_INSERT_BEFORE(other, e, entries);
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QTAILQ_INSERT_TAIL(&vm_change_state_head, e, entries);
|
2005-11-11 03:00:47 +03:00
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
2019-06-20 20:37:07 +03:00
|
|
|
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
|
|
|
|
void *opaque)
|
|
|
|
{
|
|
|
|
return qemu_add_vm_change_state_handler_prio(cb, opaque, 0);
|
|
|
|
}
|
|
|
|
|
2005-11-11 03:00:47 +03:00
|
|
|
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
|
|
|
|
{
|
2019-06-20 20:37:07 +03:00
|
|
|
QTAILQ_REMOVE(&vm_change_state_head, e, entries);
|
|
|
|
g_free(e);
|
2005-11-11 03:00:47 +03:00
|
|
|
}
|
|
|
|
|
2011-07-29 21:26:33 +04:00
|
|
|
void vm_state_notify(int running, RunState state)
|
2005-11-11 03:00:47 +03:00
|
|
|
{
|
2014-09-09 16:12:26 +04:00
|
|
|
VMChangeStateEntry *e, *next;
|
2005-11-11 03:00:47 +03:00
|
|
|
|
2019-01-24 15:51:54 +03:00
|
|
|
trace_vm_state_notify(running, state, RunState_str(state));
|
2010-11-16 15:20:25 +03:00
|
|
|
|
2019-06-20 20:37:07 +03:00
|
|
|
if (running) {
|
|
|
|
QTAILQ_FOREACH_SAFE(e, &vm_change_state_head, entries, next) {
|
|
|
|
e->cb(e->opaque, running, state);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
QTAILQ_FOREACH_REVERSE_SAFE(e, &vm_change_state_head, entries, next) {
|
|
|
|
e->cb(e->opaque, running, state);
|
|
|
|
}
|
2005-11-11 03:00:47 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
static ShutdownCause reset_requested;
|
|
|
|
static ShutdownCause shutdown_requested;
|
|
|
|
static int shutdown_signal;
|
2011-03-15 14:56:04 +03:00
|
|
|
static pid_t shutdown_pid;
|
2005-07-02 18:31:34 +04:00
|
|
|
static int powerdown_requested;
|
2011-02-07 14:19:16 +03:00
|
|
|
static int debug_requested;
|
2012-02-23 16:45:19 +04:00
|
|
|
static int suspend_requested;
|
2018-05-11 20:24:43 +03:00
|
|
|
static bool preconfig_exit_requested = true;
|
2013-09-25 20:38:29 +04:00
|
|
|
static WakeupReason wakeup_reason;
|
2012-09-06 01:06:21 +04:00
|
|
|
static NotifierList powerdown_notifiers =
|
|
|
|
NOTIFIER_LIST_INITIALIZER(powerdown_notifiers);
|
2012-02-23 16:45:19 +04:00
|
|
|
static NotifierList suspend_notifiers =
|
|
|
|
NOTIFIER_LIST_INITIALIZER(suspend_notifiers);
|
|
|
|
static NotifierList wakeup_notifiers =
|
|
|
|
NOTIFIER_LIST_INITIALIZER(wakeup_notifiers);
|
2018-12-21 17:40:33 +03:00
|
|
|
static NotifierList shutdown_notifiers =
|
|
|
|
NOTIFIER_LIST_INITIALIZER(shutdown_notifiers);
|
2013-09-25 20:38:29 +04:00
|
|
|
static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE);
|
2004-06-20 16:37:32 +04:00
|
|
|
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
ShutdownCause qemu_shutdown_requested_get(void)
|
2010-07-22 18:52:48 +04:00
|
|
|
{
|
|
|
|
return shutdown_requested;
|
|
|
|
}
|
|
|
|
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
ShutdownCause qemu_reset_requested_get(void)
|
2010-07-22 18:52:48 +04:00
|
|
|
{
|
|
|
|
return reset_requested;
|
|
|
|
}
|
|
|
|
|
2012-10-28 15:04:47 +04:00
|
|
|
static int qemu_shutdown_requested(void)
|
2008-03-18 09:53:05 +03:00
|
|
|
{
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
return atomic_xchg(&shutdown_requested, SHUTDOWN_CAUSE_NONE);
|
2008-03-18 09:53:05 +03:00
|
|
|
}
|
|
|
|
|
2012-10-28 15:04:47 +04:00
|
|
|
static void qemu_kill_report(void)
|
2011-03-15 14:56:04 +03:00
|
|
|
{
|
2017-05-16 00:41:10 +03:00
|
|
|
if (!qtest_driver() && shutdown_signal) {
|
2011-03-31 01:03:38 +04:00
|
|
|
if (shutdown_pid == 0) {
|
|
|
|
/* This happens for eg ^C at the terminal, so it's worth
|
|
|
|
* avoiding printing an odd message in that case.
|
|
|
|
*/
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("terminating on signal %d", shutdown_signal);
|
2011-03-31 01:03:38 +04:00
|
|
|
} else {
|
2016-09-27 18:24:57 +03:00
|
|
|
char *shutdown_cmd = qemu_get_pid_name(shutdown_pid);
|
|
|
|
|
|
|
|
error_report("terminating on signal %d from pid " FMT_pid " (%s)",
|
|
|
|
shutdown_signal, shutdown_pid,
|
|
|
|
shutdown_cmd ? shutdown_cmd : "<unknown process>");
|
|
|
|
g_free(shutdown_cmd);
|
2011-03-31 01:03:38 +04:00
|
|
|
}
|
2017-05-16 00:41:10 +03:00
|
|
|
shutdown_signal = 0;
|
2011-03-15 14:56:04 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
static ShutdownCause qemu_reset_requested(void)
|
2008-03-18 09:53:05 +03:00
|
|
|
{
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
ShutdownCause r = reset_requested;
|
|
|
|
|
2015-09-17 19:24:44 +03:00
|
|
|
if (r && replay_checkpoint(CHECKPOINT_RESET_REQUESTED)) {
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
reset_requested = SHUTDOWN_CAUSE_NONE;
|
2015-09-17 19:24:44 +03:00
|
|
|
return r;
|
|
|
|
}
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
return SHUTDOWN_CAUSE_NONE;
|
2008-03-18 09:53:05 +03:00
|
|
|
}
|
|
|
|
|
2012-02-23 16:45:19 +04:00
|
|
|
static int qemu_suspend_requested(void)
|
|
|
|
{
|
|
|
|
int r = suspend_requested;
|
2015-09-17 19:24:44 +03:00
|
|
|
if (r && replay_checkpoint(CHECKPOINT_SUSPEND_REQUESTED)) {
|
|
|
|
suspend_requested = 0;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
return false;
|
2012-02-23 16:45:19 +04:00
|
|
|
}
|
|
|
|
|
2013-09-25 20:38:29 +04:00
|
|
|
static WakeupReason qemu_wakeup_requested(void)
|
2012-08-09 00:29:17 +04:00
|
|
|
{
|
2013-09-25 20:38:29 +04:00
|
|
|
return wakeup_reason;
|
2012-08-09 00:29:17 +04:00
|
|
|
}
|
|
|
|
|
2012-10-28 15:04:47 +04:00
|
|
|
static int qemu_powerdown_requested(void)
|
2008-03-18 09:53:05 +03:00
|
|
|
{
|
|
|
|
int r = powerdown_requested;
|
|
|
|
powerdown_requested = 0;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2009-04-24 22:03:54 +04:00
|
|
|
static int qemu_debug_requested(void)
|
|
|
|
{
|
|
|
|
int r = debug_requested;
|
|
|
|
debug_requested = 0;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2018-05-11 20:24:43 +03:00
|
|
|
void qemu_exit_preconfig_request(void)
|
|
|
|
{
|
|
|
|
preconfig_exit_requested = true;
|
|
|
|
}
|
|
|
|
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
/*
|
|
|
|
* Reset the VM. Issue an event unless @reason is SHUTDOWN_CAUSE_NONE.
|
|
|
|
*/
|
|
|
|
void qemu_system_reset(ShutdownCause reason)
|
2012-08-07 10:41:51 +04:00
|
|
|
{
|
2014-03-05 21:30:47 +04:00
|
|
|
MachineClass *mc;
|
|
|
|
|
|
|
|
mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
|
|
|
|
|
2016-04-04 11:42:36 +03:00
|
|
|
cpu_synchronize_all_states();
|
|
|
|
|
2014-04-09 21:34:53 +04:00
|
|
|
if (mc && mc->reset) {
|
2019-05-18 23:54:20 +03:00
|
|
|
mc->reset(current_machine);
|
2012-08-07 10:41:51 +04:00
|
|
|
} else {
|
|
|
|
qemu_devices_reset();
|
|
|
|
}
|
2019-07-18 13:39:49 +03:00
|
|
|
if (reason && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
|
2018-12-05 14:01:30 +03:00
|
|
|
qapi_event_send_reset(shutdown_caused_by_guest(reason), reason);
|
2011-06-14 20:29:43 +04:00
|
|
|
}
|
2010-03-01 21:10:30 +03:00
|
|
|
cpu_synchronize_all_post_reset();
|
2004-06-20 16:37:32 +04:00
|
|
|
}
|
|
|
|
|
2019-07-22 08:32:13 +03:00
|
|
|
/*
|
|
|
|
* Wake the VM after suspend.
|
|
|
|
*/
|
|
|
|
static void qemu_system_wakeup(void)
|
|
|
|
{
|
|
|
|
MachineClass *mc;
|
|
|
|
|
|
|
|
mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
|
|
|
|
|
|
|
|
if (mc && mc->wakeup) {
|
|
|
|
mc->wakeup(current_machine);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-14 09:25:23 +03:00
|
|
|
void qemu_system_guest_panicked(GuestPanicInformation *info)
|
2015-07-03 15:01:42 +03:00
|
|
|
{
|
s390x/cpu: expose the guest crash information
This patch is the s390 implementation of guest crash information,
similar to commit d187e08dc4 ("i386/cpu: add crash-information QOM
property") and the related commits. We will detect several crash
reasons, with the "disabled wait" being the most important one, since
this is used by all s390 guests as a "panic like" notification.
Demonstrate these ways with examples as follows.
1. crash-information QOM property;
Run qemu with -qmp unix:qmp-sock,server, then use utility "qmp-shell"
to execute "qom-get" command, and might get the result like,
(QEMU) (QEMU) qom-get path=/machine/unattached/device[0] \
property=crash-information
{"return": {"core": 0, "reason": "disabled-wait", "psw-mask": 562956395872256, \
"type": "s390", "psw-addr": 1102832}}
2. GUEST_PANICKED event reporting;
Run qemu with a socket option, and telnet or nc to that,
-chardev socket,id=qmp,port=4444,host=localhost,server \
-mon chardev=qmp,mode=control,pretty=on \
Negotiating the mode by { "execute": "qmp_capabilities" }, and the crash
information will be reported on a guest crash event like,
{
"timestamp": {
"seconds": 1518004739,
"microseconds": 552563
},
"event": "GUEST_PANICKED",
"data": {
"action": "pause",
"info": {
"core": 0,
"psw-addr": 1102832,
"reason": "disabled-wait",
"psw-mask": 562956395872256,
"type": "s390"
}
}
}
3. log;
Run qemu with the parameters: -D <logfile> -d guest_errors, to
specify the logfile and log item. The results might be,
Guest crashed on cpu 0: disabled-wait
PSW: 0x0002000180000000 0x000000000010d3f0
Co-authored-by: Jing Liu <liujbjl@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Message-Id: <20180209122543.25755-1-borntraeger@de.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
[CH: tweaked qapi comment]
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2018-02-09 15:25:43 +03:00
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed");
|
2017-02-14 09:25:24 +03:00
|
|
|
|
2015-07-03 15:01:44 +03:00
|
|
|
if (current_cpu) {
|
|
|
|
current_cpu->crash_occurred = true;
|
|
|
|
}
|
2017-02-14 09:25:23 +03:00
|
|
|
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE,
|
2018-08-15 16:37:37 +03:00
|
|
|
!!info, info);
|
2015-07-03 15:01:42 +03:00
|
|
|
vm_stop(RUN_STATE_GUEST_PANICKED);
|
2016-10-18 10:29:54 +03:00
|
|
|
if (!no_shutdown) {
|
|
|
|
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
|
2018-08-15 16:37:37 +03:00
|
|
|
!!info, info);
|
2017-05-16 00:41:13 +03:00
|
|
|
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
|
2016-10-18 10:29:54 +03:00
|
|
|
}
|
2017-02-14 09:25:23 +03:00
|
|
|
|
|
|
|
if (info) {
|
2017-02-20 21:21:54 +03:00
|
|
|
if (info->type == GUEST_PANIC_INFORMATION_TYPE_HYPER_V) {
|
s390x/cpu: expose the guest crash information
This patch is the s390 implementation of guest crash information,
similar to commit d187e08dc4 ("i386/cpu: add crash-information QOM
property") and the related commits. We will detect several crash
reasons, with the "disabled wait" being the most important one, since
this is used by all s390 guests as a "panic like" notification.
Demonstrate these ways with examples as follows.
1. crash-information QOM property;
Run qemu with -qmp unix:qmp-sock,server, then use utility "qmp-shell"
to execute "qom-get" command, and might get the result like,
(QEMU) (QEMU) qom-get path=/machine/unattached/device[0] \
property=crash-information
{"return": {"core": 0, "reason": "disabled-wait", "psw-mask": 562956395872256, \
"type": "s390", "psw-addr": 1102832}}
2. GUEST_PANICKED event reporting;
Run qemu with a socket option, and telnet or nc to that,
-chardev socket,id=qmp,port=4444,host=localhost,server \
-mon chardev=qmp,mode=control,pretty=on \
Negotiating the mode by { "execute": "qmp_capabilities" }, and the crash
information will be reported on a guest crash event like,
{
"timestamp": {
"seconds": 1518004739,
"microseconds": 552563
},
"event": "GUEST_PANICKED",
"data": {
"action": "pause",
"info": {
"core": 0,
"psw-addr": 1102832,
"reason": "disabled-wait",
"psw-mask": 562956395872256,
"type": "s390"
}
}
}
3. log;
Run qemu with the parameters: -D <logfile> -d guest_errors, to
specify the logfile and log item. The results might be,
Guest crashed on cpu 0: disabled-wait
PSW: 0x0002000180000000 0x000000000010d3f0
Co-authored-by: Jing Liu <liujbjl@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Message-Id: <20180209122543.25755-1-borntraeger@de.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
[CH: tweaked qapi comment]
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2018-02-09 15:25:43 +03:00
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "\nHV crash parameters: (%#"PRIx64
|
2017-02-14 09:25:24 +03:00
|
|
|
" %#"PRIx64" %#"PRIx64" %#"PRIx64" %#"PRIx64")\n",
|
2017-02-20 21:21:54 +03:00
|
|
|
info->u.hyper_v.arg1,
|
|
|
|
info->u.hyper_v.arg2,
|
|
|
|
info->u.hyper_v.arg3,
|
|
|
|
info->u.hyper_v.arg4,
|
|
|
|
info->u.hyper_v.arg5);
|
s390x/cpu: expose the guest crash information
This patch is the s390 implementation of guest crash information,
similar to commit d187e08dc4 ("i386/cpu: add crash-information QOM
property") and the related commits. We will detect several crash
reasons, with the "disabled wait" being the most important one, since
this is used by all s390 guests as a "panic like" notification.
Demonstrate these ways with examples as follows.
1. crash-information QOM property;
Run qemu with -qmp unix:qmp-sock,server, then use utility "qmp-shell"
to execute "qom-get" command, and might get the result like,
(QEMU) (QEMU) qom-get path=/machine/unattached/device[0] \
property=crash-information
{"return": {"core": 0, "reason": "disabled-wait", "psw-mask": 562956395872256, \
"type": "s390", "psw-addr": 1102832}}
2. GUEST_PANICKED event reporting;
Run qemu with a socket option, and telnet or nc to that,
-chardev socket,id=qmp,port=4444,host=localhost,server \
-mon chardev=qmp,mode=control,pretty=on \
Negotiating the mode by { "execute": "qmp_capabilities" }, and the crash
information will be reported on a guest crash event like,
{
"timestamp": {
"seconds": 1518004739,
"microseconds": 552563
},
"event": "GUEST_PANICKED",
"data": {
"action": "pause",
"info": {
"core": 0,
"psw-addr": 1102832,
"reason": "disabled-wait",
"psw-mask": 562956395872256,
"type": "s390"
}
}
}
3. log;
Run qemu with the parameters: -D <logfile> -d guest_errors, to
specify the logfile and log item. The results might be,
Guest crashed on cpu 0: disabled-wait
PSW: 0x0002000180000000 0x000000000010d3f0
Co-authored-by: Jing Liu <liujbjl@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Message-Id: <20180209122543.25755-1-borntraeger@de.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
[CH: tweaked qapi comment]
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2018-02-09 15:25:43 +03:00
|
|
|
} else if (info->type == GUEST_PANIC_INFORMATION_TYPE_S390) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, " on cpu %d: %s\n"
|
|
|
|
"PSW: 0x%016" PRIx64 " 0x%016" PRIx64"\n",
|
|
|
|
info->u.s390.core,
|
|
|
|
S390CrashReason_str(info->u.s390.reason),
|
|
|
|
info->u.s390.psw_mask,
|
|
|
|
info->u.s390.psw_addr);
|
2017-02-14 09:25:24 +03:00
|
|
|
}
|
2017-02-14 09:25:23 +03:00
|
|
|
qapi_free_GuestPanicInformation(info);
|
|
|
|
}
|
2015-07-03 15:01:42 +03:00
|
|
|
}
|
|
|
|
|
2020-01-14 05:31:02 +03:00
|
|
|
void qemu_system_guest_crashloaded(GuestPanicInformation *info)
|
|
|
|
{
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "Guest crash loaded");
|
|
|
|
|
|
|
|
qapi_event_send_guest_crashloaded(GUEST_PANIC_ACTION_RUN,
|
|
|
|
!!info, info);
|
|
|
|
|
|
|
|
if (info) {
|
|
|
|
qapi_free_GuestPanicInformation(info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-16 00:41:13 +03:00
|
|
|
void qemu_system_reset_request(ShutdownCause reason)
|
2004-06-20 16:37:32 +04:00
|
|
|
{
|
2018-06-22 13:29:28 +03:00
|
|
|
if (no_reboot && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
|
2017-05-16 00:41:13 +03:00
|
|
|
shutdown_requested = reason;
|
2006-10-02 23:44:22 +04:00
|
|
|
} else {
|
2017-05-16 00:41:13 +03:00
|
|
|
reset_requested = reason;
|
2006-10-02 23:44:22 +04:00
|
|
|
}
|
2011-02-02 00:15:43 +03:00
|
|
|
cpu_stop_current();
|
2009-04-24 22:03:11 +04:00
|
|
|
qemu_notify_event();
|
2004-06-20 16:37:32 +04:00
|
|
|
}
|
|
|
|
|
2012-02-23 16:45:19 +04:00
|
|
|
static void qemu_system_suspend(void)
|
|
|
|
{
|
|
|
|
pause_all_vcpus();
|
|
|
|
notifier_list_notify(&suspend_notifiers, NULL);
|
2012-04-27 20:33:36 +04:00
|
|
|
runstate_set(RUN_STATE_SUSPENDED);
|
2018-08-15 16:37:37 +03:00
|
|
|
qapi_event_send_suspend();
|
2012-02-23 16:45:19 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_system_suspend_request(void)
|
|
|
|
{
|
2012-04-27 21:31:12 +04:00
|
|
|
if (runstate_check(RUN_STATE_SUSPENDED)) {
|
2012-02-23 16:45:19 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
suspend_requested = 1;
|
|
|
|
cpu_stop_current();
|
|
|
|
qemu_notify_event();
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_register_suspend_notifier(Notifier *notifier)
|
|
|
|
{
|
|
|
|
notifier_list_add(&suspend_notifiers, notifier);
|
|
|
|
}
|
|
|
|
|
qmp hmp: Make system_wakeup check wake-up support and run state
The qmp/hmp command 'system_wakeup' is simply a direct call to
'qemu_system_wakeup_request' from vl.c. This function verifies if
runstate is SUSPENDED and if the wake up reason is valid before
proceeding. However, no error or warning is thrown if any of those
pre-requirements isn't met. There is no way for the caller to
differentiate between a successful wakeup or an error state caused
when trying to wake up a guest that wasn't suspended.
This means that system_wakeup is silently failing, which can be
considered a bug. Adding error handling isn't an API break in this
case - applications that didn't check the result will remain broken,
the ones that check it will have a chance to deal with it.
Adding to that, the commit before previous created a new QMP API called
query-current-machine, with a new flag called wakeup-suspend-support,
that indicates if the guest has the capability of waking up from suspended
state. Although such guest will never reach SUSPENDED state and erroring
it out in this scenario would suffice, it is more informative for the user
to differentiate between a failure because the guest isn't suspended versus
a failure because the guest does not have support for wake up at all.
All this considered, this patch changes qmp_system_wakeup to check if
the guest is capable of waking up from suspend, and if it is suspended.
After this patch, this is the output of system_wakeup in a guest that
does not have wake-up from suspend support (ppc64):
(qemu) system_wakeup
wake-up from suspend is not supported by this guest
(qemu)
And this is the output of system_wakeup in a x86 guest that has the
support but isn't suspended:
(qemu) system_wakeup
Unable to wake up: guest is not in suspended state
(qemu)
Reported-by: Balamuruhan S <bala24@linux.vnet.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20181205194701.17836-4-danielhb413@gmail.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-05 22:47:01 +03:00
|
|
|
void qemu_system_wakeup_request(WakeupReason reason, Error **errp)
|
2012-02-23 16:45:19 +04:00
|
|
|
{
|
2014-03-07 00:03:36 +04:00
|
|
|
trace_system_wakeup_request(reason);
|
|
|
|
|
2012-04-27 21:31:12 +04:00
|
|
|
if (!runstate_check(RUN_STATE_SUSPENDED)) {
|
qmp hmp: Make system_wakeup check wake-up support and run state
The qmp/hmp command 'system_wakeup' is simply a direct call to
'qemu_system_wakeup_request' from vl.c. This function verifies if
runstate is SUSPENDED and if the wake up reason is valid before
proceeding. However, no error or warning is thrown if any of those
pre-requirements isn't met. There is no way for the caller to
differentiate between a successful wakeup or an error state caused
when trying to wake up a guest that wasn't suspended.
This means that system_wakeup is silently failing, which can be
considered a bug. Adding error handling isn't an API break in this
case - applications that didn't check the result will remain broken,
the ones that check it will have a chance to deal with it.
Adding to that, the commit before previous created a new QMP API called
query-current-machine, with a new flag called wakeup-suspend-support,
that indicates if the guest has the capability of waking up from suspended
state. Although such guest will never reach SUSPENDED state and erroring
it out in this scenario would suffice, it is more informative for the user
to differentiate between a failure because the guest isn't suspended versus
a failure because the guest does not have support for wake up at all.
All this considered, this patch changes qmp_system_wakeup to check if
the guest is capable of waking up from suspend, and if it is suspended.
After this patch, this is the output of system_wakeup in a guest that
does not have wake-up from suspend support (ppc64):
(qemu) system_wakeup
wake-up from suspend is not supported by this guest
(qemu)
And this is the output of system_wakeup in a x86 guest that has the
support but isn't suspended:
(qemu) system_wakeup
Unable to wake up: guest is not in suspended state
(qemu)
Reported-by: Balamuruhan S <bala24@linux.vnet.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20181205194701.17836-4-danielhb413@gmail.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-05 22:47:01 +03:00
|
|
|
error_setg(errp,
|
|
|
|
"Unable to wake up: guest is not in suspended state");
|
2012-02-23 16:45:19 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!(wakeup_reason_mask & (1 << reason))) {
|
|
|
|
return;
|
|
|
|
}
|
2012-04-27 20:33:36 +04:00
|
|
|
runstate_set(RUN_STATE_RUNNING);
|
2013-09-25 20:38:29 +04:00
|
|
|
wakeup_reason = reason;
|
2012-02-23 16:45:19 +04:00
|
|
|
qemu_notify_event();
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_system_wakeup_enable(WakeupReason reason, bool enabled)
|
|
|
|
{
|
|
|
|
if (enabled) {
|
|
|
|
wakeup_reason_mask |= (1 << reason);
|
|
|
|
} else {
|
|
|
|
wakeup_reason_mask &= ~(1 << reason);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_register_wakeup_notifier(Notifier *notifier)
|
|
|
|
{
|
|
|
|
notifier_list_add(&wakeup_notifiers, notifier);
|
|
|
|
}
|
|
|
|
|
qmp: query-current-machine with wakeup-suspend-support
When issuing the qmp/hmp 'system_wakeup' command, what happens in a
nutshell is:
- qmp_system_wakeup_request set runstate to RUNNING, sets a wakeup_reason
and notify the event
- in the main_loop, all vcpus are paused, a system reset is issued, all
subscribers of wakeup_notifiers receives a notification, vcpus are then
resumed and the wake up QAPI event is fired
Note that this procedure alone doesn't ensure that the guest will awake
from SUSPENDED state - the subscribers of the wake up event must take
action to resume the guest, otherwise the guest will simply reboot. At
this moment, only the ACPI machines via acpi_pm1_cnt_init and xen_hvm_init
have wake-up from suspend support.
However, only the presence of 'system_wakeup' is required for QGA to
support 'guest-suspend-ram' and 'guest-suspend-hybrid' at this moment.
This means that the user/management will expect to suspend the guest using
one of those suspend commands and then resume execution using system_wakeup,
regardless of the support offered in system_wakeup in the first place.
This patch creates a new API called query-current-machine [1], that holds
a new flag called 'wakeup-suspend-support' that indicates if the guest
supports wake up from suspend via system_wakeup. The machine is considered
to implement wake-up support if a call to a new 'qemu_register_wakeup_support'
is made during its init, as it is now being done inside acpi_pm1_cnt_init
and xen_hvm_init. This allows for any other machine type to declare wake-up
support regardless of ACPI state or wakeup_notifiers subscription, making easier
for newer implementations that might have their own mechanisms in the future.
This is the expected output of query-current-machine when running a x86
guest:
{"execute" : "query-current-machine"}
{"return": {"wakeup-suspend-support": true}}
Running the same x86 guest, but with the --no-acpi option:
{"execute" : "query-current-machine"}
{"return": {"wakeup-suspend-support": false}}
This is the output when running a pseries guest:
{"execute" : "query-current-machine"}
{"return": {"wakeup-suspend-support": false}}
With this extra tool, management can avoid situations where a guest
that does not have proper suspend/wake capabilities ends up in
inconsistent state (e.g.
https://github.com/open-power-host-os/qemu/issues/31).
[1] the decision of creating the query-current-machine API is based
on discussions in the QEMU mailing list where it was decided that
query-target wasn't a proper place to store the wake-up flag, neither
was query-machines because this isn't a static property of the
machine object. This new API can then be used to store other
dynamic machine properties that are scattered around the code
ATM. More info at:
https://lists.gnu.org/archive/html/qemu-devel/2018-05/msg04235.html
Reported-by: Balamuruhan S <bala24@linux.vnet.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20181205194701.17836-2-danielhb413@gmail.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-05 22:46:59 +03:00
|
|
|
void qemu_register_wakeup_support(void)
|
|
|
|
{
|
|
|
|
wakeup_suspend_enabled = true;
|
|
|
|
}
|
|
|
|
|
qmp hmp: Make system_wakeup check wake-up support and run state
The qmp/hmp command 'system_wakeup' is simply a direct call to
'qemu_system_wakeup_request' from vl.c. This function verifies if
runstate is SUSPENDED and if the wake up reason is valid before
proceeding. However, no error or warning is thrown if any of those
pre-requirements isn't met. There is no way for the caller to
differentiate between a successful wakeup or an error state caused
when trying to wake up a guest that wasn't suspended.
This means that system_wakeup is silently failing, which can be
considered a bug. Adding error handling isn't an API break in this
case - applications that didn't check the result will remain broken,
the ones that check it will have a chance to deal with it.
Adding to that, the commit before previous created a new QMP API called
query-current-machine, with a new flag called wakeup-suspend-support,
that indicates if the guest has the capability of waking up from suspended
state. Although such guest will never reach SUSPENDED state and erroring
it out in this scenario would suffice, it is more informative for the user
to differentiate between a failure because the guest isn't suspended versus
a failure because the guest does not have support for wake up at all.
All this considered, this patch changes qmp_system_wakeup to check if
the guest is capable of waking up from suspend, and if it is suspended.
After this patch, this is the output of system_wakeup in a guest that
does not have wake-up from suspend support (ppc64):
(qemu) system_wakeup
wake-up from suspend is not supported by this guest
(qemu)
And this is the output of system_wakeup in a x86 guest that has the
support but isn't suspended:
(qemu) system_wakeup
Unable to wake up: guest is not in suspended state
(qemu)
Reported-by: Balamuruhan S <bala24@linux.vnet.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20181205194701.17836-4-danielhb413@gmail.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-05 22:47:01 +03:00
|
|
|
bool qemu_wakeup_suspend_enabled(void)
|
qmp: query-current-machine with wakeup-suspend-support
When issuing the qmp/hmp 'system_wakeup' command, what happens in a
nutshell is:
- qmp_system_wakeup_request set runstate to RUNNING, sets a wakeup_reason
and notify the event
- in the main_loop, all vcpus are paused, a system reset is issued, all
subscribers of wakeup_notifiers receives a notification, vcpus are then
resumed and the wake up QAPI event is fired
Note that this procedure alone doesn't ensure that the guest will awake
from SUSPENDED state - the subscribers of the wake up event must take
action to resume the guest, otherwise the guest will simply reboot. At
this moment, only the ACPI machines via acpi_pm1_cnt_init and xen_hvm_init
have wake-up from suspend support.
However, only the presence of 'system_wakeup' is required for QGA to
support 'guest-suspend-ram' and 'guest-suspend-hybrid' at this moment.
This means that the user/management will expect to suspend the guest using
one of those suspend commands and then resume execution using system_wakeup,
regardless of the support offered in system_wakeup in the first place.
This patch creates a new API called query-current-machine [1], that holds
a new flag called 'wakeup-suspend-support' that indicates if the guest
supports wake up from suspend via system_wakeup. The machine is considered
to implement wake-up support if a call to a new 'qemu_register_wakeup_support'
is made during its init, as it is now being done inside acpi_pm1_cnt_init
and xen_hvm_init. This allows for any other machine type to declare wake-up
support regardless of ACPI state or wakeup_notifiers subscription, making easier
for newer implementations that might have their own mechanisms in the future.
This is the expected output of query-current-machine when running a x86
guest:
{"execute" : "query-current-machine"}
{"return": {"wakeup-suspend-support": true}}
Running the same x86 guest, but with the --no-acpi option:
{"execute" : "query-current-machine"}
{"return": {"wakeup-suspend-support": false}}
This is the output when running a pseries guest:
{"execute" : "query-current-machine"}
{"return": {"wakeup-suspend-support": false}}
With this extra tool, management can avoid situations where a guest
that does not have proper suspend/wake capabilities ends up in
inconsistent state (e.g.
https://github.com/open-power-host-os/qemu/issues/31).
[1] the decision of creating the query-current-machine API is based
on discussions in the QEMU mailing list where it was decided that
query-target wasn't a proper place to store the wake-up flag, neither
was query-machines because this isn't a static property of the
machine object. This new API can then be used to store other
dynamic machine properties that are scattered around the code
ATM. More info at:
https://lists.gnu.org/archive/html/qemu-devel/2018-05/msg04235.html
Reported-by: Balamuruhan S <bala24@linux.vnet.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20181205194701.17836-2-danielhb413@gmail.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-05 22:46:59 +03:00
|
|
|
{
|
|
|
|
return wakeup_suspend_enabled;
|
|
|
|
}
|
|
|
|
|
2011-03-15 14:56:04 +03:00
|
|
|
void qemu_system_killed(int signal, pid_t pid)
|
|
|
|
{
|
|
|
|
shutdown_signal = signal;
|
|
|
|
shutdown_pid = pid;
|
2011-09-14 17:38:40 +04:00
|
|
|
no_shutdown = 0;
|
2015-09-17 19:24:44 +03:00
|
|
|
|
|
|
|
/* Cannot call qemu_system_shutdown_request directly because
|
|
|
|
* we are in a signal handler.
|
|
|
|
*/
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL;
|
2015-09-17 19:24:44 +03:00
|
|
|
qemu_notify_event();
|
2011-03-15 14:56:04 +03:00
|
|
|
}
|
|
|
|
|
2017-05-16 00:41:13 +03:00
|
|
|
void qemu_system_shutdown_request(ShutdownCause reason)
|
2004-06-20 16:37:32 +04:00
|
|
|
{
|
2017-05-16 00:41:13 +03:00
|
|
|
trace_qemu_system_shutdown_request(reason);
|
|
|
|
replay_shutdown_request(reason);
|
|
|
|
shutdown_requested = reason;
|
2009-04-24 22:03:11 +04:00
|
|
|
qemu_notify_event();
|
2004-06-20 16:37:32 +04:00
|
|
|
}
|
|
|
|
|
2012-09-06 01:06:25 +04:00
|
|
|
static void qemu_system_powerdown(void)
|
|
|
|
{
|
2018-08-15 16:37:37 +03:00
|
|
|
qapi_event_send_powerdown();
|
2012-09-06 01:06:25 +04:00
|
|
|
notifier_list_notify(&powerdown_notifiers, NULL);
|
|
|
|
}
|
|
|
|
|
2018-12-21 17:40:33 +03:00
|
|
|
static void qemu_system_shutdown(ShutdownCause cause)
|
|
|
|
{
|
|
|
|
qapi_event_send_shutdown(shutdown_caused_by_guest(cause), cause);
|
|
|
|
notifier_list_notify(&shutdown_notifiers, &cause);
|
|
|
|
}
|
|
|
|
|
2005-07-02 18:31:34 +04:00
|
|
|
void qemu_system_powerdown_request(void)
|
|
|
|
{
|
2014-06-21 22:43:03 +04:00
|
|
|
trace_qemu_system_powerdown_request();
|
2005-07-02 18:31:34 +04:00
|
|
|
powerdown_requested = 1;
|
2009-04-24 22:03:11 +04:00
|
|
|
qemu_notify_event();
|
|
|
|
}
|
|
|
|
|
2012-09-06 01:06:21 +04:00
|
|
|
void qemu_register_powerdown_notifier(Notifier *notifier)
|
|
|
|
{
|
|
|
|
notifier_list_add(&powerdown_notifiers, notifier);
|
|
|
|
}
|
|
|
|
|
2018-12-21 17:40:33 +03:00
|
|
|
void qemu_register_shutdown_notifier(Notifier *notifier)
|
|
|
|
{
|
|
|
|
notifier_list_add(&shutdown_notifiers, notifier);
|
|
|
|
}
|
|
|
|
|
2011-02-07 14:19:16 +03:00
|
|
|
void qemu_system_debug_request(void)
|
|
|
|
{
|
|
|
|
debug_requested = 1;
|
2011-02-07 14:19:17 +03:00
|
|
|
qemu_notify_event();
|
2011-02-07 14:19:16 +03:00
|
|
|
}
|
|
|
|
|
2011-09-12 16:03:13 +04:00
|
|
|
static bool main_loop_should_exit(void)
|
|
|
|
{
|
|
|
|
RunState r;
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
ShutdownCause request;
|
|
|
|
|
2018-05-11 20:24:43 +03:00
|
|
|
if (preconfig_exit_requested) {
|
|
|
|
if (runstate_check(RUN_STATE_PRECONFIG)) {
|
|
|
|
runstate_set(RUN_STATE_PRELAUNCH);
|
|
|
|
}
|
|
|
|
preconfig_exit_requested = false;
|
|
|
|
return true;
|
|
|
|
}
|
2011-09-12 16:03:13 +04:00
|
|
|
if (qemu_debug_requested()) {
|
|
|
|
vm_stop(RUN_STATE_DEBUG);
|
|
|
|
}
|
2012-02-23 16:45:19 +04:00
|
|
|
if (qemu_suspend_requested()) {
|
|
|
|
qemu_system_suspend();
|
|
|
|
}
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
request = qemu_shutdown_requested();
|
|
|
|
if (request) {
|
2011-09-12 16:03:13 +04:00
|
|
|
qemu_kill_report();
|
2018-12-21 17:40:33 +03:00
|
|
|
qemu_system_shutdown(request);
|
2011-09-12 16:03:13 +04:00
|
|
|
if (no_shutdown) {
|
|
|
|
vm_stop(RUN_STATE_SHUTDOWN);
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
request = qemu_reset_requested();
|
|
|
|
if (request) {
|
2011-09-12 16:03:13 +04:00
|
|
|
pause_all_vcpus();
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
qemu_system_reset(request);
|
2011-09-12 16:03:13 +04:00
|
|
|
resume_all_vcpus();
|
2019-11-29 14:51:32 +03:00
|
|
|
/*
|
|
|
|
* runstate can change in pause_all_vcpus()
|
|
|
|
* as iothread mutex is unlocked
|
|
|
|
*/
|
2016-02-13 16:26:26 +03:00
|
|
|
if (!runstate_check(RUN_STATE_RUNNING) &&
|
2019-11-29 14:51:32 +03:00
|
|
|
!runstate_check(RUN_STATE_INMIGRATE) &&
|
|
|
|
!runstate_check(RUN_STATE_FINISH_MIGRATE)) {
|
2016-02-13 16:26:26 +03:00
|
|
|
runstate_set(RUN_STATE_PRELAUNCH);
|
2011-09-12 16:03:13 +04:00
|
|
|
}
|
|
|
|
}
|
2012-08-09 00:29:17 +04:00
|
|
|
if (qemu_wakeup_requested()) {
|
|
|
|
pause_all_vcpus();
|
2019-07-22 08:32:13 +03:00
|
|
|
qemu_system_wakeup();
|
2013-09-25 20:38:29 +04:00
|
|
|
notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
|
|
|
|
wakeup_reason = QEMU_WAKEUP_REASON_NONE;
|
2012-08-09 00:29:17 +04:00
|
|
|
resume_all_vcpus();
|
2018-08-15 16:37:37 +03:00
|
|
|
qapi_event_send_wakeup();
|
2012-08-09 00:29:17 +04:00
|
|
|
}
|
2011-09-12 16:03:13 +04:00
|
|
|
if (qemu_powerdown_requested()) {
|
2012-09-06 01:06:25 +04:00
|
|
|
qemu_system_powerdown();
|
2011-09-12 16:03:13 +04:00
|
|
|
}
|
|
|
|
if (qemu_vmstop_requested(&r)) {
|
|
|
|
vm_stop(r);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-02-20 07:10:58 +03:00
|
|
|
void qemu_main_loop(void)
|
2009-04-24 22:03:33 +04:00
|
|
|
{
|
2011-02-02 00:15:46 +03:00
|
|
|
#ifdef CONFIG_PROFILER
|
|
|
|
int64_t ti;
|
|
|
|
#endif
|
2018-06-05 17:00:42 +03:00
|
|
|
while (!main_loop_should_exit()) {
|
2006-02-09 01:46:31 +03:00
|
|
|
#ifdef CONFIG_PROFILER
|
2011-02-02 00:15:47 +03:00
|
|
|
ti = profile_getclock();
|
2006-02-09 01:46:31 +03:00
|
|
|
#endif
|
2017-03-03 13:51:07 +03:00
|
|
|
main_loop_wait(false);
|
2006-02-09 01:46:31 +03:00
|
|
|
#ifdef CONFIG_PROFILER
|
2011-02-02 00:15:47 +03:00
|
|
|
dev_time += profile_getclock() - ti;
|
2006-02-09 01:46:31 +03:00
|
|
|
#endif
|
2018-06-05 17:00:42 +03:00
|
|
|
}
|
2003-06-27 21:34:32 +04:00
|
|
|
}
|
|
|
|
|
2009-04-08 02:58:45 +04:00
|
|
|
static void version(void)
|
|
|
|
{
|
2018-02-15 14:06:47 +03:00
|
|
|
printf("QEMU emulator version " QEMU_FULL_VERSION "\n"
|
2016-08-04 14:14:36 +03:00
|
|
|
QEMU_COPYRIGHT "\n");
|
2009-04-08 02:58:45 +04:00
|
|
|
}
|
|
|
|
|
2007-06-30 03:26:08 +04:00
|
|
|
static void help(int exitcode)
|
2003-06-24 17:42:40 +04:00
|
|
|
{
|
2011-12-19 10:19:31 +04:00
|
|
|
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());
|
|
|
|
|
2011-12-19 10:19:30 +04:00
|
|
|
#define QEMU_OPTIONS_GENERATE_HELP
|
|
|
|
#include "qemu-options-wrapper.h"
|
2011-12-19 10:19:31 +04:00
|
|
|
|
|
|
|
printf("\nDuring emulation, the following keys are useful:\n"
|
2010-02-08 12:04:56 +03:00
|
|
|
"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"
|
2017-08-03 19:33:53 +03:00
|
|
|
"When using -nographic, press 'ctrl-a h' to get some help.\n"
|
|
|
|
"\n"
|
|
|
|
QEMU_HELP_BOTTOM "\n");
|
2011-12-19 10:19:31 +04:00
|
|
|
|
2007-06-30 03:26:08 +04:00
|
|
|
exit(exitcode);
|
2003-06-24 17:42:40 +04:00
|
|
|
}
|
|
|
|
|
2004-05-14 02:02:20 +04:00
|
|
|
#define HAS_ARG 0x0001
|
|
|
|
|
|
|
|
typedef struct QEMUOption {
|
|
|
|
const char *name;
|
|
|
|
int flags;
|
|
|
|
int index;
|
2010-03-29 23:23:52 +04:00
|
|
|
uint32_t arch_mask;
|
2004-05-14 02:02:20 +04:00
|
|
|
} QEMUOption;
|
|
|
|
|
2008-10-01 23:38:09 +04:00
|
|
|
static const QEMUOption qemu_options[] = {
|
2010-03-29 23:23:52 +04:00
|
|
|
{ "h", 0, QEMU_OPTION_h, QEMU_ARCH_ALL },
|
2011-12-19 10:19:30 +04:00
|
|
|
#define QEMU_OPTIONS_GENERATE_OPTIONS
|
|
|
|
#include "qemu-options-wrapper.h"
|
2004-05-14 02:02:20 +04:00
|
|
|
{ NULL },
|
2003-06-30 14:03:06 +04:00
|
|
|
};
|
2011-09-27 23:15:42 +04:00
|
|
|
|
2015-10-29 00:19:58 +03:00
|
|
|
typedef struct VGAInterfaceInfo {
|
|
|
|
const char *opt_name; /* option name */
|
|
|
|
const char *name; /* human-readable name */
|
2015-11-11 23:55:56 +03:00
|
|
|
/* Class names indicating that support is available.
|
|
|
|
* If no class is specified, the interface is always available */
|
|
|
|
const char *class_names[2];
|
2015-10-29 00:19:58 +03:00
|
|
|
} VGAInterfaceInfo;
|
|
|
|
|
2019-04-12 18:27:12 +03:00
|
|
|
static const VGAInterfaceInfo vga_interfaces[VGA_TYPE_MAX] = {
|
2015-10-29 00:19:58 +03:00
|
|
|
[VGA_NONE] = {
|
|
|
|
.opt_name = "none",
|
2019-04-12 19:37:06 +03:00
|
|
|
.name = "no graphic card",
|
2015-10-29 00:19:58 +03:00
|
|
|
},
|
|
|
|
[VGA_STD] = {
|
|
|
|
.opt_name = "std",
|
|
|
|
.name = "standard VGA",
|
2015-11-11 23:55:56 +03:00
|
|
|
.class_names = { "VGA", "isa-vga" },
|
2015-10-29 00:19:58 +03:00
|
|
|
},
|
|
|
|
[VGA_CIRRUS] = {
|
|
|
|
.opt_name = "cirrus",
|
|
|
|
.name = "Cirrus VGA",
|
2015-11-11 23:55:56 +03:00
|
|
|
.class_names = { "cirrus-vga", "isa-cirrus-vga" },
|
2015-10-29 00:19:58 +03:00
|
|
|
},
|
|
|
|
[VGA_VMWARE] = {
|
|
|
|
.opt_name = "vmware",
|
|
|
|
.name = "VMWare SVGA",
|
2015-11-11 23:55:56 +03:00
|
|
|
.class_names = { "vmware-svga" },
|
2015-10-29 00:19:58 +03:00
|
|
|
},
|
|
|
|
[VGA_VIRTIO] = {
|
|
|
|
.opt_name = "virtio",
|
|
|
|
.name = "Virtio VGA",
|
2015-11-11 23:55:56 +03:00
|
|
|
.class_names = { "virtio-vga" },
|
2015-10-29 00:19:58 +03:00
|
|
|
},
|
|
|
|
[VGA_QXL] = {
|
|
|
|
.opt_name = "qxl",
|
|
|
|
.name = "QXL VGA",
|
2015-11-11 23:55:56 +03:00
|
|
|
.class_names = { "qxl-vga" },
|
2015-10-29 00:19:58 +03:00
|
|
|
},
|
|
|
|
[VGA_TCX] = {
|
|
|
|
.opt_name = "tcx",
|
|
|
|
.name = "TCX framebuffer",
|
2015-11-11 23:55:56 +03:00
|
|
|
.class_names = { "SUNW,tcx" },
|
2015-10-29 00:19:58 +03:00
|
|
|
},
|
|
|
|
[VGA_CG3] = {
|
|
|
|
.opt_name = "cg3",
|
|
|
|
.name = "CG3 framebuffer",
|
2015-11-11 23:55:56 +03:00
|
|
|
.class_names = { "cgthree" },
|
2015-10-29 00:19:58 +03:00
|
|
|
},
|
|
|
|
[VGA_XENFB] = {
|
|
|
|
.opt_name = "xenfb",
|
2019-04-12 19:37:06 +03:00
|
|
|
.name = "Xen paravirtualized framebuffer",
|
2015-10-29 00:19:58 +03:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2015-11-11 23:55:56 +03:00
|
|
|
static bool vga_interface_available(VGAInterfaceType t)
|
|
|
|
{
|
2019-04-12 18:27:12 +03:00
|
|
|
const VGAInterfaceInfo *ti = &vga_interfaces[t];
|
2015-11-11 23:55:56 +03:00
|
|
|
|
|
|
|
assert(t < VGA_TYPE_MAX);
|
|
|
|
return !ti->class_names[0] ||
|
|
|
|
object_class_by_name(ti->class_names[0]) ||
|
|
|
|
object_class_by_name(ti->class_names[1]);
|
|
|
|
}
|
|
|
|
|
2019-04-12 18:27:13 +03:00
|
|
|
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)
|
2008-09-28 04:42:05 +04:00
|
|
|
{
|
|
|
|
const char *opts;
|
2015-10-29 00:19:58 +03:00
|
|
|
int t;
|
2008-09-28 04:42:05 +04:00
|
|
|
|
2019-04-12 18:27:13 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-03-10 18:37:40 +04:00
|
|
|
assert(vga_interface_type == VGA_NONE);
|
2015-10-29 00:19:58 +03:00
|
|
|
for (t = 0; t < VGA_TYPE_MAX; t++) {
|
2019-04-12 18:27:12 +03:00
|
|
|
const VGAInterfaceInfo *ti = &vga_interfaces[t];
|
2015-10-29 00:19:58 +03:00
|
|
|
if (ti->opt_name && strstart(p, ti->opt_name, &opts)) {
|
2015-11-11 23:55:56 +03:00
|
|
|
if (!vga_interface_available(t)) {
|
2015-10-29 00:19:58 +03:00
|
|
|
error_report("%s not available", ti->name);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
vga_interface_type = t;
|
|
|
|
break;
|
2013-10-16 00:03:04 +04:00
|
|
|
}
|
2015-10-29 00:19:58 +03:00
|
|
|
}
|
|
|
|
if (t == VGA_TYPE_MAX) {
|
2008-09-28 04:42:05 +04:00
|
|
|
invalid_vga:
|
2015-10-30 18:07:58 +03:00
|
|
|
error_report("unknown vga type: %s", p);
|
2008-09-28 04:42:05 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
2008-09-28 04:42:12 +04:00
|
|
|
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;
|
|
|
|
}
|
2008-09-28 04:42:05 +04:00
|
|
|
}
|
|
|
|
|
2018-05-07 12:55:36 +03:00
|
|
|
static void parse_display_qapi(const char *optarg)
|
|
|
|
{
|
|
|
|
DisplayOptions *opts;
|
|
|
|
Visitor *v;
|
|
|
|
|
2018-10-17 11:26:26 +03:00
|
|
|
v = qobject_input_visitor_new_str(optarg, "type", &error_fatal);
|
2018-05-07 12:55:36 +03:00
|
|
|
|
|
|
|
visit_type_DisplayOptions(v, NULL, &opts, &error_fatal);
|
|
|
|
QAPI_CLONE_MEMBERS(DisplayOptions, &dpy, opts);
|
|
|
|
|
|
|
|
qapi_free_DisplayOptions(opts);
|
|
|
|
visit_free(v);
|
|
|
|
}
|
|
|
|
|
2018-11-22 10:16:13 +03:00
|
|
|
DisplayOptions *qmp_query_display_options(Error **errp)
|
|
|
|
{
|
|
|
|
return QAPI_CLONE(DisplayOptions, &dpy);
|
|
|
|
}
|
|
|
|
|
2018-02-02 14:10:22 +03:00
|
|
|
static void parse_display(const char *p)
|
2011-03-16 15:33:31 +03:00
|
|
|
{
|
|
|
|
const char *opts;
|
|
|
|
|
2020-01-08 17:47:02 +03:00
|
|
|
if (is_help_option(p)) {
|
|
|
|
qemu_display_help();
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2011-03-16 15:33:31 +03:00
|
|
|
if (strstart(p, "sdl", &opts)) {
|
2018-05-07 12:55:39 +03:00
|
|
|
/*
|
|
|
|
* sdl DisplayType needs hand-crafted parser instead of
|
|
|
|
* parse_display_qapi() due to some options not in
|
|
|
|
* DisplayOptions, specifically:
|
|
|
|
* - frame
|
|
|
|
* Already deprecated.
|
|
|
|
* - ctrl_grab + alt_grab
|
|
|
|
* Not clear yet what happens to them long-term. Should
|
|
|
|
* replaced by something better or deprecated and dropped.
|
|
|
|
*/
|
2018-02-02 14:10:15 +03:00
|
|
|
dpy.type = DISPLAY_TYPE_SDL;
|
2011-03-16 15:33:31 +03:00
|
|
|
while (*opts) {
|
|
|
|
const char *nextopt;
|
|
|
|
|
2019-02-05 10:29:29 +03:00
|
|
|
if (strstart(opts, ",alt_grab=", &nextopt)) {
|
2011-03-16 15:33:31 +03:00
|
|
|
opts = nextopt;
|
|
|
|
if (strstart(opts, "on", &nextopt)) {
|
|
|
|
alt_grab = 1;
|
|
|
|
} else if (strstart(opts, "off", &nextopt)) {
|
|
|
|
alt_grab = 0;
|
|
|
|
} else {
|
2011-03-23 06:40:57 +03:00
|
|
|
goto invalid_sdl_args;
|
2011-03-16 15:33:31 +03:00
|
|
|
}
|
|
|
|
} 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 {
|
2011-03-23 06:40:57 +03:00
|
|
|
goto invalid_sdl_args;
|
2011-03-16 15:33:31 +03:00
|
|
|
}
|
|
|
|
} else if (strstart(opts, ",window_close=", &nextopt)) {
|
|
|
|
opts = nextopt;
|
2018-02-02 14:10:15 +03:00
|
|
|
dpy.has_window_close = true;
|
2011-03-16 15:33:31 +03:00
|
|
|
if (strstart(opts, "on", &nextopt)) {
|
2018-02-02 14:10:15 +03:00
|
|
|
dpy.window_close = true;
|
2011-03-16 15:33:31 +03:00
|
|
|
} else if (strstart(opts, "off", &nextopt)) {
|
2018-02-02 14:10:15 +03:00
|
|
|
dpy.window_close = false;
|
2011-03-16 15:33:31 +03:00
|
|
|
} else {
|
2011-03-23 06:40:57 +03:00
|
|
|
goto invalid_sdl_args;
|
2011-03-16 15:33:31 +03:00
|
|
|
}
|
2020-01-31 14:35:21 +03:00
|
|
|
} 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;
|
|
|
|
}
|
2014-11-11 18:54:45 +03:00
|
|
|
} else if (strstart(opts, ",gl=", &nextopt)) {
|
|
|
|
opts = nextopt;
|
2018-02-02 14:10:15 +03:00
|
|
|
dpy.has_gl = true;
|
2014-11-11 18:54:45 +03:00
|
|
|
if (strstart(opts, "on", &nextopt)) {
|
2018-04-13 16:58:40 +03:00
|
|
|
dpy.gl = DISPLAYGL_MODE_ON;
|
2018-04-13 16:58:42 +03:00
|
|
|
} else if (strstart(opts, "core", &nextopt)) {
|
|
|
|
dpy.gl = DISPLAYGL_MODE_CORE;
|
|
|
|
} else if (strstart(opts, "es", &nextopt)) {
|
|
|
|
dpy.gl = DISPLAYGL_MODE_ES;
|
2014-11-11 18:54:45 +03:00
|
|
|
} else if (strstart(opts, "off", &nextopt)) {
|
2018-04-13 16:58:40 +03:00
|
|
|
dpy.gl = DISPLAYGL_MODE_OFF;
|
2014-11-11 18:54:45 +03:00
|
|
|
} else {
|
|
|
|
goto invalid_sdl_args;
|
|
|
|
}
|
2011-03-16 15:33:31 +03:00
|
|
|
} else {
|
2011-03-23 06:40:57 +03:00
|
|
|
invalid_sdl_args:
|
2015-10-30 18:07:58 +03:00
|
|
|
error_report("invalid SDL option string");
|
2011-03-23 06:40:57 +03:00
|
|
|
exit(1);
|
2011-03-16 15:33:31 +03:00
|
|
|
}
|
|
|
|
opts = nextopt;
|
|
|
|
}
|
2011-03-16 15:33:33 +03:00
|
|
|
} else if (strstart(p, "vnc", &opts)) {
|
2018-05-07 12:55:39 +03:00
|
|
|
/*
|
|
|
|
* vnc isn't a (local) DisplayType but a protocol for remote
|
|
|
|
* display access.
|
|
|
|
*/
|
2014-09-16 14:33:03 +04:00
|
|
|
if (*opts == '=') {
|
2016-05-12 17:09:59 +03:00
|
|
|
vnc_parse(opts + 1, &error_fatal);
|
2014-09-16 14:33:03 +04:00
|
|
|
} else {
|
2015-02-13 20:23:45 +03:00
|
|
|
error_report("VNC requires a display argument vnc=<display>");
|
2011-03-16 15:33:33 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
2011-03-16 15:33:31 +03:00
|
|
|
} else {
|
2018-05-07 12:55:36 +03:00
|
|
|
parse_display_qapi(p);
|
2011-03-16 15:33:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-30 03:52:44 +04:00
|
|
|
char *qemu_find_file(int type, const char *name)
|
|
|
|
{
|
2013-03-08 14:42:24 +04:00
|
|
|
int i;
|
2009-05-30 03:52:44 +04:00
|
|
|
const char *subdir;
|
|
|
|
char *buf;
|
|
|
|
|
2012-05-25 16:07:01 +04:00
|
|
|
/* Try the name as a straight path first */
|
|
|
|
if (access(name, R_OK) == 0) {
|
2013-03-08 14:42:24 +04:00
|
|
|
trace_load_file(name, name);
|
2011-08-21 07:09:37 +04:00
|
|
|
return g_strdup(name);
|
2009-05-30 03:52:44 +04:00
|
|
|
}
|
2013-03-08 14:42:24 +04:00
|
|
|
|
2009-05-30 03:52:44 +04:00
|
|
|
switch (type) {
|
|
|
|
case QEMU_FILE_TYPE_BIOS:
|
|
|
|
subdir = "";
|
|
|
|
break;
|
|
|
|
case QEMU_FILE_TYPE_KEYMAP:
|
|
|
|
subdir = "keymaps/";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
}
|
2013-03-08 14:42:24 +04:00
|
|
|
|
|
|
|
for (i = 0; i < data_dir_idx; i++) {
|
|
|
|
buf = g_strdup_printf("%s/%s%s", data_dir[i], subdir, name);
|
|
|
|
if (access(buf, R_OK) == 0) {
|
|
|
|
trace_load_file(name, buf);
|
|
|
|
return buf;
|
|
|
|
}
|
2011-08-21 07:09:37 +04:00
|
|
|
g_free(buf);
|
2009-05-30 03:52:44 +04:00
|
|
|
}
|
2013-03-08 14:42:24 +04:00
|
|
|
return NULL;
|
2009-05-30 03:52:44 +04:00
|
|
|
}
|
|
|
|
|
2017-09-14 14:42:35 +03:00
|
|
|
static void qemu_add_data_dir(const char *path)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (path == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (data_dir_idx == ARRAY_SIZE(data_dir)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (i = 0; i < data_dir_idx; i++) {
|
|
|
|
if (strcmp(data_dir[i], path) == 0) {
|
|
|
|
return; /* duplicate */
|
|
|
|
}
|
|
|
|
}
|
2018-01-04 19:05:14 +03:00
|
|
|
data_dir[data_dir_idx++] = g_strdup(path);
|
2017-09-14 14:42:35 +03:00
|
|
|
}
|
|
|
|
|
2015-09-29 19:29:01 +03:00
|
|
|
static inline bool nonempty_str(const char *str)
|
|
|
|
{
|
|
|
|
return str && *str;
|
|
|
|
}
|
|
|
|
|
2015-04-29 18:21:53 +03:00
|
|
|
static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
|
|
|
|
{
|
|
|
|
gchar *buf;
|
|
|
|
size_t size;
|
2015-09-29 19:29:01 +03:00
|
|
|
const char *name, *file, *str;
|
2016-04-07 17:12:58 +03:00
|
|
|
FWCfgState *fw_cfg = (FWCfgState *) opaque;
|
2015-04-29 18:21:53 +03:00
|
|
|
|
2016-04-07 17:12:58 +03:00
|
|
|
if (fw_cfg == NULL) {
|
2018-10-17 11:26:47 +03:00
|
|
|
error_setg(errp, "fw_cfg device not available");
|
2015-04-29 18:21:53 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
name = qemu_opt_get(opts, "name");
|
|
|
|
file = qemu_opt_get(opts, "file");
|
2015-09-29 19:29:01 +03:00
|
|
|
str = qemu_opt_get(opts, "string");
|
|
|
|
|
|
|
|
/* we need name and either a file or the content string */
|
|
|
|
if (!(nonempty_str(name) && (nonempty_str(file) || nonempty_str(str)))) {
|
2018-10-17 11:26:47 +03:00
|
|
|
error_setg(errp, "invalid argument(s)");
|
2015-09-29 19:29:01 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (nonempty_str(file) && nonempty_str(str)) {
|
2018-10-17 11:26:47 +03:00
|
|
|
error_setg(errp, "file and string are mutually exclusive");
|
2015-04-29 18:21:53 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (strlen(name) > FW_CFG_MAX_FILE_PATH - 1) {
|
2018-10-17 11:26:47 +03:00
|
|
|
error_setg(errp, "name too long (max. %d char)",
|
|
|
|
FW_CFG_MAX_FILE_PATH - 1);
|
2015-04-29 18:21:53 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (strncmp(name, "opt/", 4) != 0) {
|
2017-07-12 16:57:41 +03:00
|
|
|
warn_report("externally provided fw_cfg item names "
|
|
|
|
"should be prefixed with \"opt/\"");
|
2015-04-29 18:21:53 +03:00
|
|
|
}
|
2015-09-29 19:29:01 +03:00
|
|
|
if (nonempty_str(str)) {
|
|
|
|
size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */
|
|
|
|
buf = g_memdup(str, size);
|
|
|
|
} else {
|
2018-11-01 08:59:31 +03:00
|
|
|
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);
|
2015-09-29 19:29:01 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2015-04-29 18:21:53 +03:00
|
|
|
}
|
2016-04-07 17:12:58 +03:00
|
|
|
/* 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);
|
2015-04-29 18:21:53 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-13 15:35:14 +03:00
|
|
|
static int device_help_func(void *opaque, QemuOpts *opts, Error **errp)
|
2010-01-29 21:48:57 +03:00
|
|
|
{
|
|
|
|
return qdev_device_help(opts);
|
|
|
|
}
|
|
|
|
|
2015-03-13 15:35:14 +03:00
|
|
|
static int device_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
2009-07-31 14:25:37 +04:00
|
|
|
{
|
|
|
|
DeviceState *dev;
|
|
|
|
|
2018-10-17 11:26:48 +03:00
|
|
|
dev = qdev_device_add(opts, errp);
|
2019-10-29 14:48:55 +03:00
|
|
|
if (!dev && *errp) {
|
|
|
|
error_report_err(*errp);
|
2009-07-31 14:25:37 +04:00
|
|
|
return -1;
|
2019-10-29 14:48:55 +03:00
|
|
|
} else if (dev) {
|
|
|
|
object_unref(OBJECT(dev));
|
2015-03-12 16:00:41 +03:00
|
|
|
}
|
2009-07-31 14:25:37 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-13 15:35:14 +03:00
|
|
|
static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
2009-12-08 15:11:36 +03:00
|
|
|
{
|
2012-10-15 11:28:05 +04:00
|
|
|
Error *local_err = NULL;
|
2009-12-08 15:11:36 +03:00
|
|
|
|
2019-02-13 16:18:13 +03:00
|
|
|
if (!qemu_chr_new_from_opts(opts, NULL, &local_err)) {
|
2017-07-25 13:04:41 +03:00
|
|
|
if (local_err) {
|
2018-10-17 11:26:44 +03:00
|
|
|
error_propagate(errp, local_err);
|
2017-07-25 13:04:41 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
exit(0);
|
2012-10-15 11:28:05 +04:00
|
|
|
}
|
2009-12-08 15:11:36 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-06-15 00:34:41 +04:00
|
|
|
#ifdef CONFIG_VIRTFS
|
2015-03-13 15:35:14 +03:00
|
|
|
static int fsdev_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
2010-04-29 16:14:43 +04:00
|
|
|
{
|
2018-10-17 11:26:55 +03:00
|
|
|
return qemu_fsdev_add(opts, errp);
|
2010-04-29 16:14:43 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-03-13 15:35:14 +03:00
|
|
|
static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
2009-12-08 15:11:50 +03:00
|
|
|
{
|
2020-01-29 13:22:36 +03:00
|
|
|
return monitor_init_opts(opts, errp);
|
2009-12-08 15:11:50 +03:00
|
|
|
}
|
|
|
|
|
2014-11-17 15:31:04 +03:00
|
|
|
static void monitor_parse(const char *optarg, const char *mode, bool pretty)
|
2009-12-08 15:11:50 +03:00
|
|
|
{
|
|
|
|
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 {
|
2010-04-06 18:55:52 +04:00
|
|
|
snprintf(label, sizeof(label), "compat_monitor%d",
|
|
|
|
monitor_device_index);
|
chardev: mark the calls that allow an implicit mux monitor
This is mostly for readability of the code. Let's make it clear which
callers can create an implicit monitor when the chardev is muxed.
This will also enforce a safer behaviour, as we don't really support
creating monitor anywhere/anytime at the moment. Add an assert() to
make sure the programmer explicitely wanted that behaviour.
There are documented cases, such as: -serial/-parallel/-virtioconsole
and to less extent -debugcon.
Less obvious and questionable ones are -gdb, SLIRP -guestfwd and Xen
console. Add a FIXME note for those, but keep the support for now.
Other qemu_chr_new() callers either have a fixed parameter/filename
string or do not need it, such as -qtest:
* qtest.c: qtest_init()
Afaik, only used by tests/libqtest.c, without mux. I don't think we
support it outside of qemu testing: drop support for implicit mux
monitor (qemu_chr_new() call: no implicit mux now).
* hw/
All with literal @filename argument that doesn't enable mux monitor.
* tests/
All with @filename argument that doesn't enable mux monitor.
On a related note, the list of monitor creation places:
- the chardev creators listed above: all from command line (except
perhaps Xen console?)
- -gdb & hmp gdbserver will create a "GDB monitor command" chardev
that is wired to an HMP monitor.
- -mon command line option
From this short study, I would like to think that a monitor may only
be created in the main thread today, though I remain skeptical :)
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
2018-08-22 20:19:42 +03:00
|
|
|
opts = qemu_chr_parse_compat(label, optarg, true);
|
2009-12-08 15:11:50 +03:00
|
|
|
if (!opts) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("parse error: %s", optarg);
|
2009-12-08 15:11:50 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-12 17:10:00 +03:00
|
|
|
opts = qemu_opts_create(qemu_find_opts("mon"), label, 1, &error_fatal);
|
2015-02-12 19:52:20 +03:00
|
|
|
qemu_opt_set(opts, "mode", mode, &error_abort);
|
|
|
|
qemu_opt_set(opts, "chardev", label, &error_abort);
|
2019-06-13 18:34:05 +03:00
|
|
|
if (!strcmp(mode, "control")) {
|
|
|
|
qemu_opt_set_bool(opts, "pretty", pretty, &error_abort);
|
|
|
|
} else {
|
|
|
|
assert(pretty == false);
|
|
|
|
}
|
2009-12-08 15:11:50 +03:00
|
|
|
monitor_device_index++;
|
|
|
|
}
|
|
|
|
|
2009-07-15 15:59:26 +04:00
|
|
|
struct device_config {
|
|
|
|
enum {
|
2009-12-08 15:11:53 +03:00
|
|
|
DEV_USB, /* -usbdevice */
|
|
|
|
DEV_SERIAL, /* -serial */
|
|
|
|
DEV_PARALLEL, /* -parallel */
|
debugcon: support for debugging consoles (e.g. Bochs port 0xe9)
Add generic support for debugging consoles (simple I/O ports which
when written to cause debugging output to be written to a target.)
The current implementation matches Bochs' port 0xe9, allowing the same
debugging code to be used for both Bochs and Qemu.
There is no vm state associated with the debugging port, simply
because it has none -- the entire interface is a single, stateless,
write-only port.
Most of the code was cribbed from the serial port driver.
v2: removed non-ISA variants (they can be introduced when/if someone
wants them, using code from the serial port); added configurable
readback (Bochs returns 0xe9 on a read from this register, mimic that
by default) This retains the apparently somewhat controversial user
friendly option, however.
v3: reimplemented the user friendly option as a synthetic option
("-debugcon foo" basically ends up being a parser-level shorthand for
"-chardev stdio,id=debugcon -device isa-debugcon,chardev=debugcon") --
this dramatically reduced the complexity while keeping the same level
of user friendliness.
v4: spaces, not tabs.
v5: update to match current top of tree. Calling qemu_chr_open()
already during parsing no longer works; defer until we are parsing the
other console-like devices.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-30 00:51:36 +03:00
|
|
|
DEV_DEBUGCON, /* -debugcon */
|
2012-02-07 18:09:13 +04:00
|
|
|
DEV_GDB, /* -gdb, -s */
|
2013-01-24 15:18:52 +04:00
|
|
|
DEV_SCLP, /* s390 sclp */
|
2009-07-15 15:59:26 +04:00
|
|
|
} type;
|
|
|
|
const char *cmdline;
|
2012-02-07 18:09:12 +04:00
|
|
|
Location loc;
|
2009-09-12 11:36:22 +04:00
|
|
|
QTAILQ_ENTRY(device_config) next;
|
2009-07-15 15:59:26 +04:00
|
|
|
};
|
2012-10-28 15:04:47 +04:00
|
|
|
|
|
|
|
static QTAILQ_HEAD(, device_config) device_configs =
|
|
|
|
QTAILQ_HEAD_INITIALIZER(device_configs);
|
2009-07-15 15:59:26 +04:00
|
|
|
|
|
|
|
static void add_device_config(int type, const char *cmdline)
|
|
|
|
{
|
|
|
|
struct device_config *conf;
|
|
|
|
|
2011-08-21 07:09:37 +04:00
|
|
|
conf = g_malloc0(sizeof(*conf));
|
2009-07-15 15:59:26 +04:00
|
|
|
conf->type = type;
|
|
|
|
conf->cmdline = cmdline;
|
2012-02-07 18:09:12 +04:00
|
|
|
loc_save(&conf->loc);
|
2009-09-12 11:36:22 +04:00
|
|
|
QTAILQ_INSERT_TAIL(&device_configs, conf, next);
|
2009-07-15 15:59:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static int foreach_device_config(int type, int (*func)(const char *cmdline))
|
|
|
|
{
|
|
|
|
struct device_config *conf;
|
|
|
|
int rc;
|
|
|
|
|
2009-09-12 11:36:22 +04:00
|
|
|
QTAILQ_FOREACH(conf, &device_configs, next) {
|
2009-07-15 15:59:26 +04:00
|
|
|
if (conf->type != type)
|
|
|
|
continue;
|
2012-02-07 18:09:12 +04:00
|
|
|
loc_push_restore(&conf->loc);
|
2009-07-15 15:59:26 +04:00
|
|
|
rc = func(conf->cmdline);
|
2012-02-07 18:09:12 +04:00
|
|
|
loc_pop(&conf->loc);
|
2014-08-11 17:00:57 +04:00
|
|
|
if (rc) {
|
2009-07-15 15:59:26 +04:00
|
|
|
return rc;
|
2014-08-11 17:00:57 +04:00
|
|
|
}
|
2009-07-15 15:59:26 +04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-08 15:11:41 +03:00
|
|
|
static int serial_parse(const char *devname)
|
|
|
|
{
|
2018-04-20 17:52:48 +03:00
|
|
|
int index = num_serial_hds;
|
2009-12-08 15:11:41 +03:00
|
|
|
char label[32];
|
|
|
|
|
|
|
|
if (strcmp(devname, "none") == 0)
|
|
|
|
return 0;
|
|
|
|
snprintf(label, sizeof(label), "serial%d", index);
|
2018-04-20 17:52:48 +03:00
|
|
|
serial_hds = g_renew(Chardev *, serial_hds, index + 1);
|
|
|
|
|
2019-02-13 16:18:13 +03:00
|
|
|
serial_hds[index] = qemu_chr_new_mux_mon(label, devname, NULL);
|
2009-12-08 15:11:41 +03:00
|
|
|
if (!serial_hds[index]) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("could not connect serial device"
|
|
|
|
" to character backend '%s'", devname);
|
2009-12-08 15:11:41 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2018-04-20 17:52:48 +03:00
|
|
|
num_serial_hds++;
|
2009-12-08 15:11:41 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-04-20 17:52:42 +03:00
|
|
|
Chardev *serial_hd(int i)
|
|
|
|
{
|
|
|
|
assert(i >= 0);
|
2018-04-20 17:52:48 +03:00
|
|
|
if (i < num_serial_hds) {
|
2018-04-20 17:52:42 +03:00
|
|
|
return serial_hds[i];
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-04-20 17:52:49 +03:00
|
|
|
int serial_max_hds(void)
|
|
|
|
{
|
|
|
|
return num_serial_hds;
|
|
|
|
}
|
|
|
|
|
2009-12-08 15:11:42 +03:00
|
|
|
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) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("too many parallel ports");
|
2009-12-08 15:11:42 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
snprintf(label, sizeof(label), "parallel%d", index);
|
2019-02-13 16:18:13 +03:00
|
|
|
parallel_hds[index] = qemu_chr_new_mux_mon(label, devname, NULL);
|
2009-12-08 15:11:42 +03:00
|
|
|
if (!parallel_hds[index]) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("could not connect parallel device"
|
|
|
|
" to character backend '%s'", devname);
|
2009-12-08 15:11:42 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
index++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
debugcon: support for debugging consoles (e.g. Bochs port 0xe9)
Add generic support for debugging consoles (simple I/O ports which
when written to cause debugging output to be written to a target.)
The current implementation matches Bochs' port 0xe9, allowing the same
debugging code to be used for both Bochs and Qemu.
There is no vm state associated with the debugging port, simply
because it has none -- the entire interface is a single, stateless,
write-only port.
Most of the code was cribbed from the serial port driver.
v2: removed non-ISA variants (they can be introduced when/if someone
wants them, using code from the serial port); added configurable
readback (Bochs returns 0xe9 on a read from this register, mimic that
by default) This retains the apparently somewhat controversial user
friendly option, however.
v3: reimplemented the user friendly option as a synthetic option
("-debugcon foo" basically ends up being a parser-level shorthand for
"-chardev stdio,id=debugcon -device isa-debugcon,chardev=debugcon") --
this dramatically reduced the complexity while keeping the same level
of user friendliness.
v4: spaces, not tabs.
v5: update to match current top of tree. Calling qemu_chr_open()
already during parsing no longer works; defer until we are parsing the
other console-like devices.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-30 00:51:36 +03:00
|
|
|
static int debugcon_parse(const char *devname)
|
2013-03-21 03:23:13 +04:00
|
|
|
{
|
debugcon: support for debugging consoles (e.g. Bochs port 0xe9)
Add generic support for debugging consoles (simple I/O ports which
when written to cause debugging output to be written to a target.)
The current implementation matches Bochs' port 0xe9, allowing the same
debugging code to be used for both Bochs and Qemu.
There is no vm state associated with the debugging port, simply
because it has none -- the entire interface is a single, stateless,
write-only port.
Most of the code was cribbed from the serial port driver.
v2: removed non-ISA variants (they can be introduced when/if someone
wants them, using code from the serial port); added configurable
readback (Bochs returns 0xe9 on a read from this register, mimic that
by default) This retains the apparently somewhat controversial user
friendly option, however.
v3: reimplemented the user friendly option as a synthetic option
("-debugcon foo" basically ends up being a parser-level shorthand for
"-chardev stdio,id=debugcon -device isa-debugcon,chardev=debugcon") --
this dramatically reduced the complexity while keeping the same level
of user friendliness.
v4: spaces, not tabs.
v5: update to match current top of tree. Calling qemu_chr_open()
already during parsing no longer works; defer until we are parsing the
other console-like devices.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-30 00:51:36 +03:00
|
|
|
QemuOpts *opts;
|
|
|
|
|
2019-02-13 16:18:13 +03:00
|
|
|
if (!qemu_chr_new_mux_mon("debugcon", devname, NULL)) {
|
2018-10-11 20:12:54 +03:00
|
|
|
error_report("invalid character backend '%s'", devname);
|
debugcon: support for debugging consoles (e.g. Bochs port 0xe9)
Add generic support for debugging consoles (simple I/O ports which
when written to cause debugging output to be written to a target.)
The current implementation matches Bochs' port 0xe9, allowing the same
debugging code to be used for both Bochs and Qemu.
There is no vm state associated with the debugging port, simply
because it has none -- the entire interface is a single, stateless,
write-only port.
Most of the code was cribbed from the serial port driver.
v2: removed non-ISA variants (they can be introduced when/if someone
wants them, using code from the serial port); added configurable
readback (Bochs returns 0xe9 on a read from this register, mimic that
by default) This retains the apparently somewhat controversial user
friendly option, however.
v3: reimplemented the user friendly option as a synthetic option
("-debugcon foo" basically ends up being a parser-level shorthand for
"-chardev stdio,id=debugcon -device isa-debugcon,chardev=debugcon") --
this dramatically reduced the complexity while keeping the same level
of user friendliness.
v4: spaces, not tabs.
v5: update to match current top of tree. Calling qemu_chr_open()
already during parsing no longer works; defer until we are parsing the
other console-like devices.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-30 00:51:36 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
2012-03-20 22:51:57 +04:00
|
|
|
opts = qemu_opts_create(qemu_find_opts("device"), "debugcon", 1, NULL);
|
debugcon: support for debugging consoles (e.g. Bochs port 0xe9)
Add generic support for debugging consoles (simple I/O ports which
when written to cause debugging output to be written to a target.)
The current implementation matches Bochs' port 0xe9, allowing the same
debugging code to be used for both Bochs and Qemu.
There is no vm state associated with the debugging port, simply
because it has none -- the entire interface is a single, stateless,
write-only port.
Most of the code was cribbed from the serial port driver.
v2: removed non-ISA variants (they can be introduced when/if someone
wants them, using code from the serial port); added configurable
readback (Bochs returns 0xe9 on a read from this register, mimic that
by default) This retains the apparently somewhat controversial user
friendly option, however.
v3: reimplemented the user friendly option as a synthetic option
("-debugcon foo" basically ends up being a parser-level shorthand for
"-chardev stdio,id=debugcon -device isa-debugcon,chardev=debugcon") --
this dramatically reduced the complexity while keeping the same level
of user friendliness.
v4: spaces, not tabs.
v5: update to match current top of tree. Calling qemu_chr_open()
already during parsing no longer works; defer until we are parsing the
other console-like devices.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-30 00:51:36 +03:00
|
|
|
if (!opts) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("already have a debugcon device");
|
debugcon: support for debugging consoles (e.g. Bochs port 0xe9)
Add generic support for debugging consoles (simple I/O ports which
when written to cause debugging output to be written to a target.)
The current implementation matches Bochs' port 0xe9, allowing the same
debugging code to be used for both Bochs and Qemu.
There is no vm state associated with the debugging port, simply
because it has none -- the entire interface is a single, stateless,
write-only port.
Most of the code was cribbed from the serial port driver.
v2: removed non-ISA variants (they can be introduced when/if someone
wants them, using code from the serial port); added configurable
readback (Bochs returns 0xe9 on a read from this register, mimic that
by default) This retains the apparently somewhat controversial user
friendly option, however.
v3: reimplemented the user friendly option as a synthetic option
("-debugcon foo" basically ends up being a parser-level shorthand for
"-chardev stdio,id=debugcon -device isa-debugcon,chardev=debugcon") --
this dramatically reduced the complexity while keeping the same level
of user friendliness.
v4: spaces, not tabs.
v5: update to match current top of tree. Calling qemu_chr_open()
already during parsing no longer works; defer until we are parsing the
other console-like devices.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-30 00:51:36 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
2015-02-12 19:52:20 +03:00
|
|
|
qemu_opt_set(opts, "driver", "isa-debugcon", &error_abort);
|
|
|
|
qemu_opt_set(opts, "chardev", "debugcon", &error_abort);
|
debugcon: support for debugging consoles (e.g. Bochs port 0xe9)
Add generic support for debugging consoles (simple I/O ports which
when written to cause debugging output to be written to a target.)
The current implementation matches Bochs' port 0xe9, allowing the same
debugging code to be used for both Bochs and Qemu.
There is no vm state associated with the debugging port, simply
because it has none -- the entire interface is a single, stateless,
write-only port.
Most of the code was cribbed from the serial port driver.
v2: removed non-ISA variants (they can be introduced when/if someone
wants them, using code from the serial port); added configurable
readback (Bochs returns 0xe9 on a read from this register, mimic that
by default) This retains the apparently somewhat controversial user
friendly option, however.
v3: reimplemented the user friendly option as a synthetic option
("-debugcon foo" basically ends up being a parser-level shorthand for
"-chardev stdio,id=debugcon -device isa-debugcon,chardev=debugcon") --
this dramatically reduced the complexity while keeping the same level
of user friendliness.
v4: spaces, not tabs.
v5: update to match current top of tree. Calling qemu_chr_open()
already during parsing no longer works; defer until we are parsing the
other console-like devices.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-30 00:51:36 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
well-defined listing order for machine types
Commit 261747f1 ("vl: Use MachineClass instead of global QEMUMachine
list") broke the ordering of the machine types in the user-visible output
of
qemu-system-XXXX -M \?
This occurred because registration was rebased from a manually maintained
linked list to GLib hash tables:
qemu_register_machine()
type_register()
type_register_internal()
type_table_add()
g_hash_table_insert()
and because the listing was rebased accordingly, from the traversal of the
list to the traversal of the hash table (rendered as an ad-hoc list):
machine_parse()
object_class_get_list(TYPE_MACHINE)
object_class_foreach()
g_hash_table_foreach()
The current order is a "random" one, for practical purposes, which is
annoying for users.
Introduce new members QEMUMachine.family and MachineClass.family, allowing
machine types to be "clustered". Introduce a comparator function that
establishes a total ordering between machine types, ordering machine types
in the same family next to each other. In machine_parse(), list the
supported machine types sorted with the comparator function.
The comparator function:
- sorts whole families before standalone machine types,
- sorts whole families between each other in alphabetically increasing
order,
- sorts machine types inside the same family in alphabetically decreasing
order,
- sorts standalone machine types between each other in alphabetically
increasing order.
After this patch, all machine types are considered standalone, and
accordingly, the output is alphabetically ascending. This will be refined
in the following patches.
Effects on the x86_64 output:
Before:
> Supported machines are:
> pc-0.13 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-2.0 Standard PC (i440FX + PIIX, 1996)
> pc-1.0 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-2.1 Standard PC (i440FX + PIIX, 1996)
> pc-q35-1.7 Standard PC (Q35 + ICH9, 2009)
> pc-1.1 Standard PC (i440FX + PIIX, 1996)
> pc-0.14 Standard PC (i440FX + PIIX, 1996)
> pc-q35-2.0 Standard PC (Q35 + ICH9, 2009)
> pc-i440fx-1.4 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.5 Standard PC (i440FX + PIIX, 1996)
> pc-0.15 Standard PC (i440FX + PIIX, 1996)
> pc-q35-1.4 Standard PC (Q35 + ICH9, 2009)
> isapc ISA-only PC
> pc Standard PC (i440FX + PIIX, 1996) (alias of pc-i440fx-2.2)
> pc-i440fx-2.2 Standard PC (i440FX + PIIX, 1996) (default)
> pc-1.2 Standard PC (i440FX + PIIX, 1996)
> pc-0.10 Standard PC (i440FX + PIIX, 1996)
> pc-0.11 Standard PC (i440FX + PIIX, 1996)
> pc-q35-2.1 Standard PC (Q35 + ICH9, 2009)
> q35 Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-2.2)
> pc-q35-2.2 Standard PC (Q35 + ICH9, 2009)
> pc-i440fx-1.6 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.7 Standard PC (i440FX + PIIX, 1996)
> none empty machine
> pc-q35-1.5 Standard PC (Q35 + ICH9, 2009)
> pc-q35-1.6 Standard PC (Q35 + ICH9, 2009)
> pc-0.12 Standard PC (i440FX + PIIX, 1996)
> pc-1.3 Standard PC (i440FX + PIIX, 1996)
After:
> Supported machines are:
> isapc ISA-only PC
> none empty machine
> pc-0.10 Standard PC (i440FX + PIIX, 1996)
> pc-0.11 Standard PC (i440FX + PIIX, 1996)
> pc-0.12 Standard PC (i440FX + PIIX, 1996)
> pc-0.13 Standard PC (i440FX + PIIX, 1996)
> pc-0.14 Standard PC (i440FX + PIIX, 1996)
> pc-0.15 Standard PC (i440FX + PIIX, 1996)
> pc-1.0 Standard PC (i440FX + PIIX, 1996)
> pc-1.1 Standard PC (i440FX + PIIX, 1996)
> pc-1.2 Standard PC (i440FX + PIIX, 1996)
> pc-1.3 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.4 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.5 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.6 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.7 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-2.0 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-2.1 Standard PC (i440FX + PIIX, 1996)
> pc Standard PC (i440FX + PIIX, 1996) (alias of pc-i440fx-2.2)
> pc-i440fx-2.2 Standard PC (i440FX + PIIX, 1996) (default)
> pc-q35-1.4 Standard PC (Q35 + ICH9, 2009)
> pc-q35-1.5 Standard PC (Q35 + ICH9, 2009)
> pc-q35-1.6 Standard PC (Q35 + ICH9, 2009)
> pc-q35-1.7 Standard PC (Q35 + ICH9, 2009)
> pc-q35-2.0 Standard PC (Q35 + ICH9, 2009)
> pc-q35-2.1 Standard PC (Q35 + ICH9, 2009)
> q35 Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-2.2)
> pc-q35-2.2 Standard PC (Q35 + ICH9, 2009)
Effects on the aarch64 output:
Before:
> Supported machines are:
> lm3s811evb Stellaris LM3S811EVB
> canon-a1100 Canon PowerShot A1100 IS
> vexpress-a15 ARM Versatile Express for Cortex-A15
> vexpress-a9 ARM Versatile Express for Cortex-A9
> xilinx-zynq-a9 Xilinx Zynq Platform Baseboard for Cortex-A9
> connex Gumstix Connex (PXA255)
> n800 Nokia N800 tablet aka. RX-34 (OMAP2420)
> lm3s6965evb Stellaris LM3S6965EVB
> versatileab ARM Versatile/AB (ARM926EJ-S)
> borzoi Borzoi PDA (PXA270)
> tosa Tosa PDA (PXA255)
> cheetah Palm Tungsten|E aka. Cheetah PDA (OMAP310)
> midway Calxeda Midway (ECX-2000)
> mainstone Mainstone II (PXA27x)
> n810 Nokia N810 tablet aka. RX-44 (OMAP2420)
> terrier Terrier PDA (PXA270)
> highbank Calxeda Highbank (ECX-1000)
> cubieboard cubietech cubieboard
> sx1-v1 Siemens SX1 (OMAP310) V1
> sx1 Siemens SX1 (OMAP310) V2
> realview-eb-mpcore ARM RealView Emulation Baseboard (ARM11MPCore)
> kzm ARM KZM Emulation Baseboard (ARM1136)
> akita Akita PDA (PXA270)
> z2 Zipit Z2 (PXA27x)
> musicpal Marvell 88w8618 / MusicPal (ARM926EJ-S)
> realview-pb-a8 ARM RealView Platform Baseboard for Cortex-A8
> versatilepb ARM Versatile/PB (ARM926EJ-S)
> realview-eb ARM RealView Emulation Baseboard (ARM926EJ-S)
> realview-pbx-a9 ARM RealView Platform Baseboard Explore for Cortex-A9
> spitz Spitz PDA (PXA270)
> none empty machine
> virt ARM Virtual Machine
> collie Collie PDA (SA-1110)
> smdkc210 Samsung SMDKC210 board (Exynos4210)
> verdex Gumstix Verdex (PXA270)
> nuri Samsung NURI board (Exynos4210)
> integratorcp ARM Integrator/CP (ARM926EJ-S)
After:
> Supported machines are:
> akita Akita PDA (PXA270)
> borzoi Borzoi PDA (PXA270)
> canon-a1100 Canon PowerShot A1100 IS
> cheetah Palm Tungsten|E aka. Cheetah PDA (OMAP310)
> collie Collie PDA (SA-1110)
> connex Gumstix Connex (PXA255)
> cubieboard cubietech cubieboard
> highbank Calxeda Highbank (ECX-1000)
> integratorcp ARM Integrator/CP (ARM926EJ-S)
> kzm ARM KZM Emulation Baseboard (ARM1136)
> lm3s6965evb Stellaris LM3S6965EVB
> lm3s811evb Stellaris LM3S811EVB
> mainstone Mainstone II (PXA27x)
> midway Calxeda Midway (ECX-2000)
> musicpal Marvell 88w8618 / MusicPal (ARM926EJ-S)
> n800 Nokia N800 tablet aka. RX-34 (OMAP2420)
> n810 Nokia N810 tablet aka. RX-44 (OMAP2420)
> none empty machine
> nuri Samsung NURI board (Exynos4210)
> realview-eb ARM RealView Emulation Baseboard (ARM926EJ-S)
> realview-eb-mpcore ARM RealView Emulation Baseboard (ARM11MPCore)
> realview-pb-a8 ARM RealView Platform Baseboard for Cortex-A8
> realview-pbx-a9 ARM RealView Platform Baseboard Explore for Cortex-A9
> smdkc210 Samsung SMDKC210 board (Exynos4210)
> spitz Spitz PDA (PXA270)
> sx1 Siemens SX1 (OMAP310) V2
> sx1-v1 Siemens SX1 (OMAP310) V1
> terrier Terrier PDA (PXA270)
> tosa Tosa PDA (PXA255)
> verdex Gumstix Verdex (PXA270)
> versatileab ARM Versatile/AB (ARM926EJ-S)
> versatilepb ARM Versatile/PB (ARM926EJ-S)
> vexpress-a15 ARM Versatile Express for Cortex-A15
> vexpress-a9 ARM Versatile Express for Cortex-A9
> virt ARM Virtual Machine
> xilinx-zynq-a9 Xilinx Zynq Platform Baseboard for Cortex-A9
> z2 Zipit Z2 (PXA27x)
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1145042
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel.a@redhat.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-23 00:38:35 +04:00
|
|
|
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)));
|
|
|
|
}
|
|
|
|
|
2019-04-05 09:41:19 +03:00
|
|
|
static MachineClass *machine_parse(const char *name, GSList *machines)
|
2011-07-23 14:38:37 +04:00
|
|
|
{
|
2019-04-05 09:41:21 +03:00
|
|
|
MachineClass *mc;
|
2019-04-05 09:41:19 +03:00
|
|
|
GSList *el;
|
2011-07-23 14:38:37 +04:00
|
|
|
|
2019-04-05 09:41:21 +03:00
|
|
|
if (is_help_option(name)) {
|
2014-03-14 16:06:54 +04:00
|
|
|
printf("Supported machines are:\n");
|
well-defined listing order for machine types
Commit 261747f1 ("vl: Use MachineClass instead of global QEMUMachine
list") broke the ordering of the machine types in the user-visible output
of
qemu-system-XXXX -M \?
This occurred because registration was rebased from a manually maintained
linked list to GLib hash tables:
qemu_register_machine()
type_register()
type_register_internal()
type_table_add()
g_hash_table_insert()
and because the listing was rebased accordingly, from the traversal of the
list to the traversal of the hash table (rendered as an ad-hoc list):
machine_parse()
object_class_get_list(TYPE_MACHINE)
object_class_foreach()
g_hash_table_foreach()
The current order is a "random" one, for practical purposes, which is
annoying for users.
Introduce new members QEMUMachine.family and MachineClass.family, allowing
machine types to be "clustered". Introduce a comparator function that
establishes a total ordering between machine types, ordering machine types
in the same family next to each other. In machine_parse(), list the
supported machine types sorted with the comparator function.
The comparator function:
- sorts whole families before standalone machine types,
- sorts whole families between each other in alphabetically increasing
order,
- sorts machine types inside the same family in alphabetically decreasing
order,
- sorts standalone machine types between each other in alphabetically
increasing order.
After this patch, all machine types are considered standalone, and
accordingly, the output is alphabetically ascending. This will be refined
in the following patches.
Effects on the x86_64 output:
Before:
> Supported machines are:
> pc-0.13 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-2.0 Standard PC (i440FX + PIIX, 1996)
> pc-1.0 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-2.1 Standard PC (i440FX + PIIX, 1996)
> pc-q35-1.7 Standard PC (Q35 + ICH9, 2009)
> pc-1.1 Standard PC (i440FX + PIIX, 1996)
> pc-0.14 Standard PC (i440FX + PIIX, 1996)
> pc-q35-2.0 Standard PC (Q35 + ICH9, 2009)
> pc-i440fx-1.4 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.5 Standard PC (i440FX + PIIX, 1996)
> pc-0.15 Standard PC (i440FX + PIIX, 1996)
> pc-q35-1.4 Standard PC (Q35 + ICH9, 2009)
> isapc ISA-only PC
> pc Standard PC (i440FX + PIIX, 1996) (alias of pc-i440fx-2.2)
> pc-i440fx-2.2 Standard PC (i440FX + PIIX, 1996) (default)
> pc-1.2 Standard PC (i440FX + PIIX, 1996)
> pc-0.10 Standard PC (i440FX + PIIX, 1996)
> pc-0.11 Standard PC (i440FX + PIIX, 1996)
> pc-q35-2.1 Standard PC (Q35 + ICH9, 2009)
> q35 Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-2.2)
> pc-q35-2.2 Standard PC (Q35 + ICH9, 2009)
> pc-i440fx-1.6 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.7 Standard PC (i440FX + PIIX, 1996)
> none empty machine
> pc-q35-1.5 Standard PC (Q35 + ICH9, 2009)
> pc-q35-1.6 Standard PC (Q35 + ICH9, 2009)
> pc-0.12 Standard PC (i440FX + PIIX, 1996)
> pc-1.3 Standard PC (i440FX + PIIX, 1996)
After:
> Supported machines are:
> isapc ISA-only PC
> none empty machine
> pc-0.10 Standard PC (i440FX + PIIX, 1996)
> pc-0.11 Standard PC (i440FX + PIIX, 1996)
> pc-0.12 Standard PC (i440FX + PIIX, 1996)
> pc-0.13 Standard PC (i440FX + PIIX, 1996)
> pc-0.14 Standard PC (i440FX + PIIX, 1996)
> pc-0.15 Standard PC (i440FX + PIIX, 1996)
> pc-1.0 Standard PC (i440FX + PIIX, 1996)
> pc-1.1 Standard PC (i440FX + PIIX, 1996)
> pc-1.2 Standard PC (i440FX + PIIX, 1996)
> pc-1.3 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.4 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.5 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.6 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.7 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-2.0 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-2.1 Standard PC (i440FX + PIIX, 1996)
> pc Standard PC (i440FX + PIIX, 1996) (alias of pc-i440fx-2.2)
> pc-i440fx-2.2 Standard PC (i440FX + PIIX, 1996) (default)
> pc-q35-1.4 Standard PC (Q35 + ICH9, 2009)
> pc-q35-1.5 Standard PC (Q35 + ICH9, 2009)
> pc-q35-1.6 Standard PC (Q35 + ICH9, 2009)
> pc-q35-1.7 Standard PC (Q35 + ICH9, 2009)
> pc-q35-2.0 Standard PC (Q35 + ICH9, 2009)
> pc-q35-2.1 Standard PC (Q35 + ICH9, 2009)
> q35 Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-2.2)
> pc-q35-2.2 Standard PC (Q35 + ICH9, 2009)
Effects on the aarch64 output:
Before:
> Supported machines are:
> lm3s811evb Stellaris LM3S811EVB
> canon-a1100 Canon PowerShot A1100 IS
> vexpress-a15 ARM Versatile Express for Cortex-A15
> vexpress-a9 ARM Versatile Express for Cortex-A9
> xilinx-zynq-a9 Xilinx Zynq Platform Baseboard for Cortex-A9
> connex Gumstix Connex (PXA255)
> n800 Nokia N800 tablet aka. RX-34 (OMAP2420)
> lm3s6965evb Stellaris LM3S6965EVB
> versatileab ARM Versatile/AB (ARM926EJ-S)
> borzoi Borzoi PDA (PXA270)
> tosa Tosa PDA (PXA255)
> cheetah Palm Tungsten|E aka. Cheetah PDA (OMAP310)
> midway Calxeda Midway (ECX-2000)
> mainstone Mainstone II (PXA27x)
> n810 Nokia N810 tablet aka. RX-44 (OMAP2420)
> terrier Terrier PDA (PXA270)
> highbank Calxeda Highbank (ECX-1000)
> cubieboard cubietech cubieboard
> sx1-v1 Siemens SX1 (OMAP310) V1
> sx1 Siemens SX1 (OMAP310) V2
> realview-eb-mpcore ARM RealView Emulation Baseboard (ARM11MPCore)
> kzm ARM KZM Emulation Baseboard (ARM1136)
> akita Akita PDA (PXA270)
> z2 Zipit Z2 (PXA27x)
> musicpal Marvell 88w8618 / MusicPal (ARM926EJ-S)
> realview-pb-a8 ARM RealView Platform Baseboard for Cortex-A8
> versatilepb ARM Versatile/PB (ARM926EJ-S)
> realview-eb ARM RealView Emulation Baseboard (ARM926EJ-S)
> realview-pbx-a9 ARM RealView Platform Baseboard Explore for Cortex-A9
> spitz Spitz PDA (PXA270)
> none empty machine
> virt ARM Virtual Machine
> collie Collie PDA (SA-1110)
> smdkc210 Samsung SMDKC210 board (Exynos4210)
> verdex Gumstix Verdex (PXA270)
> nuri Samsung NURI board (Exynos4210)
> integratorcp ARM Integrator/CP (ARM926EJ-S)
After:
> Supported machines are:
> akita Akita PDA (PXA270)
> borzoi Borzoi PDA (PXA270)
> canon-a1100 Canon PowerShot A1100 IS
> cheetah Palm Tungsten|E aka. Cheetah PDA (OMAP310)
> collie Collie PDA (SA-1110)
> connex Gumstix Connex (PXA255)
> cubieboard cubietech cubieboard
> highbank Calxeda Highbank (ECX-1000)
> integratorcp ARM Integrator/CP (ARM926EJ-S)
> kzm ARM KZM Emulation Baseboard (ARM1136)
> lm3s6965evb Stellaris LM3S6965EVB
> lm3s811evb Stellaris LM3S811EVB
> mainstone Mainstone II (PXA27x)
> midway Calxeda Midway (ECX-2000)
> musicpal Marvell 88w8618 / MusicPal (ARM926EJ-S)
> n800 Nokia N800 tablet aka. RX-34 (OMAP2420)
> n810 Nokia N810 tablet aka. RX-44 (OMAP2420)
> none empty machine
> nuri Samsung NURI board (Exynos4210)
> realview-eb ARM RealView Emulation Baseboard (ARM926EJ-S)
> realview-eb-mpcore ARM RealView Emulation Baseboard (ARM11MPCore)
> realview-pb-a8 ARM RealView Platform Baseboard for Cortex-A8
> realview-pbx-a9 ARM RealView Platform Baseboard Explore for Cortex-A9
> smdkc210 Samsung SMDKC210 board (Exynos4210)
> spitz Spitz PDA (PXA270)
> sx1 Siemens SX1 (OMAP310) V2
> sx1-v1 Siemens SX1 (OMAP310) V1
> terrier Terrier PDA (PXA270)
> tosa Tosa PDA (PXA255)
> verdex Gumstix Verdex (PXA270)
> versatileab ARM Versatile/AB (ARM926EJ-S)
> versatilepb ARM Versatile/PB (ARM926EJ-S)
> vexpress-a15 ARM Versatile Express for Cortex-A15
> vexpress-a9 ARM Versatile Express for Cortex-A9
> virt ARM Virtual Machine
> xilinx-zynq-a9 Xilinx Zynq Platform Baseboard for Cortex-A9
> z2 Zipit Z2 (PXA27x)
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1145042
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel.a@redhat.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-23 00:38:35 +04:00
|
|
|
machines = g_slist_sort(machines, machine_class_cmp);
|
2014-03-14 16:06:54 +04:00
|
|
|
for (el = machines; el; el = el->next) {
|
|
|
|
MachineClass *mc = el->data;
|
2014-04-09 21:34:53 +04:00
|
|
|
if (mc->alias) {
|
|
|
|
printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
|
2014-03-14 16:06:54 +04:00
|
|
|
}
|
2018-06-25 12:05:12 +03:00
|
|
|
printf("%-20s %s%s%s\n", mc->name, mc->desc,
|
|
|
|
mc->is_default ? " (default)" : "",
|
|
|
|
mc->deprecation_reason ? " (deprecated)" : "");
|
2011-07-23 14:38:37 +04:00
|
|
|
}
|
2019-04-05 09:41:21 +03:00
|
|
|
exit(0);
|
2011-07-23 14:38:37 +04:00
|
|
|
}
|
2014-03-05 21:30:46 +04:00
|
|
|
|
2019-04-05 09:41:21 +03:00
|
|
|
mc = find_machine(name, machines);
|
|
|
|
if (!mc) {
|
|
|
|
error_report("unsupported machine type");
|
|
|
|
error_printf("Use -machine help to list supported machines\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
return mc;
|
2011-07-23 14:38:37 +04:00
|
|
|
}
|
|
|
|
|
2010-06-04 16:08:07 +04:00
|
|
|
void qemu_add_exit_notifier(Notifier *notify)
|
|
|
|
{
|
|
|
|
notifier_list_add(&exit_notifiers, notify);
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_remove_exit_notifier(Notifier *notify)
|
|
|
|
{
|
2012-01-13 20:34:01 +04:00
|
|
|
notifier_remove(notify);
|
2010-06-04 16:08:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void qemu_run_exit_notifiers(void)
|
|
|
|
{
|
2011-06-20 16:06:26 +04:00
|
|
|
notifier_list_notify(&exit_notifiers, NULL);
|
2010-06-04 16:08:07 +04:00
|
|
|
}
|
|
|
|
|
2018-09-07 15:13:19 +03:00
|
|
|
static const char *pid_file;
|
|
|
|
static Notifier qemu_unlink_pidfile_notifier;
|
|
|
|
|
|
|
|
static void qemu_unlink_pidfile(Notifier *n, void *data)
|
|
|
|
{
|
|
|
|
if (pid_file) {
|
|
|
|
unlink(pid_file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-06 08:33:12 +03:00
|
|
|
bool machine_init_done;
|
2015-03-31 15:01:06 +03:00
|
|
|
|
2010-12-08 14:35:08 +03:00
|
|
|
void qemu_add_machine_init_done_notifier(Notifier *notify)
|
|
|
|
{
|
|
|
|
notifier_list_add(&machine_init_done_notifiers, notify);
|
2015-03-31 15:01:06 +03:00
|
|
|
if (machine_init_done) {
|
|
|
|
notify->notify(notify, NULL);
|
|
|
|
}
|
2010-12-08 14:35:08 +03:00
|
|
|
}
|
|
|
|
|
2016-06-27 18:38:32 +03:00
|
|
|
void qemu_remove_machine_init_done_notifier(Notifier *notify)
|
|
|
|
{
|
|
|
|
notifier_remove(notify);
|
|
|
|
}
|
|
|
|
|
2010-12-08 14:35:08 +03:00
|
|
|
static void qemu_run_machine_init_done_notifiers(void)
|
|
|
|
{
|
2015-03-31 15:01:06 +03:00
|
|
|
machine_init_done = true;
|
2018-03-06 08:33:12 +03:00
|
|
|
notifier_list_notify(&machine_init_done_notifiers, NULL);
|
2010-12-08 14:35:08 +03:00
|
|
|
}
|
|
|
|
|
2010-01-22 18:18:06 +03:00
|
|
|
static const QEMUOption *lookup_opt(int argc, char **argv,
|
|
|
|
const char **poptarg, int *poptind)
|
|
|
|
{
|
|
|
|
const QEMUOption *popt;
|
|
|
|
int optind = *poptind;
|
|
|
|
char *r = argv[optind];
|
|
|
|
const char *optarg;
|
|
|
|
|
2010-02-18 22:13:51 +03:00
|
|
|
loc_set_cmdline(argv, optind, 1);
|
2010-01-22 18:18:06 +03:00
|
|
|
optind++;
|
|
|
|
/* Treat --foo the same as -foo. */
|
|
|
|
if (r[1] == '-')
|
|
|
|
r++;
|
|
|
|
popt = qemu_options;
|
|
|
|
for(;;) {
|
|
|
|
if (!popt->name) {
|
2010-02-18 22:13:51 +03:00
|
|
|
error_report("invalid option");
|
2010-01-22 18:18:06 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (!strcmp(popt->name, r + 1))
|
|
|
|
break;
|
|
|
|
popt++;
|
|
|
|
}
|
|
|
|
if (popt->flags & HAS_ARG) {
|
|
|
|
if (optind >= argc) {
|
2010-02-18 22:13:51 +03:00
|
|
|
error_report("requires an argument");
|
2010-01-22 18:18:06 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
optarg = argv[optind++];
|
2010-02-18 22:13:51 +03:00
|
|
|
loc_set_cmdline(argv, optind - 2, 2);
|
2010-01-22 18:18:06 +03:00
|
|
|
} else {
|
|
|
|
optarg = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*poptarg = optarg;
|
|
|
|
*poptind = optind;
|
|
|
|
|
|
|
|
return popt;
|
|
|
|
}
|
|
|
|
|
2016-02-16 17:51:53 +03:00
|
|
|
static MachineClass *select_machine(void)
|
2016-02-12 22:02:24 +03:00
|
|
|
{
|
2019-04-05 09:41:19 +03:00
|
|
|
GSList *machines = object_class_get_list(TYPE_MACHINE, false);
|
|
|
|
MachineClass *machine_class = find_default_machine(machines);
|
2016-02-12 22:02:24 +03:00
|
|
|
const char *optarg;
|
|
|
|
QemuOpts *opts;
|
|
|
|
Location loc;
|
|
|
|
|
|
|
|
loc_push_none(&loc);
|
|
|
|
|
|
|
|
opts = qemu_get_machine_opts();
|
|
|
|
qemu_opts_loc_restore(opts);
|
|
|
|
|
|
|
|
optarg = qemu_opt_get(opts, "type");
|
|
|
|
if (optarg) {
|
2019-04-05 09:41:19 +03:00
|
|
|
machine_class = machine_parse(optarg, machines);
|
2016-02-12 22:02:24 +03:00
|
|
|
}
|
|
|
|
|
2016-02-16 17:51:53 +03:00
|
|
|
if (!machine_class) {
|
2016-02-12 22:02:24 +03:00
|
|
|
error_report("No machine specified, and there is no default");
|
|
|
|
error_printf("Use -machine help to list supported machines\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
loc_pop(&loc);
|
2019-04-05 09:41:19 +03:00
|
|
|
g_slist_free(machines);
|
2016-02-16 17:51:53 +03:00
|
|
|
return machine_class;
|
2016-02-12 22:02:24 +03:00
|
|
|
}
|
|
|
|
|
2019-11-13 13:44:48 +03:00
|
|
|
static int object_parse_property_opt(Object *obj,
|
|
|
|
const char *name, const char *value,
|
|
|
|
const char *skip, Error **errp)
|
2012-06-25 23:36:33 +04:00
|
|
|
{
|
|
|
|
Error *local_err = NULL;
|
|
|
|
|
2019-11-13 13:44:48 +03:00
|
|
|
if (g_str_equal(name, skip)) {
|
2012-06-25 23:36:33 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-11-13 13:44:48 +03:00
|
|
|
object_property_parse(obj, value, name, &local_err);
|
2012-06-25 23:36:33 +04:00
|
|
|
|
|
|
|
if (local_err) {
|
2018-10-17 11:26:45 +03:00
|
|
|
error_propagate(errp, local_err);
|
2012-06-25 23:36:33 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-11-13 13:44:48 +03:00
|
|
|
static int machine_set_property(void *opaque,
|
|
|
|
const char *name, const char *value,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
g_autofree char *qom_name = g_strdup(name);
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
for (p = qom_name; *p; p++) {
|
|
|
|
if (*p == '_') {
|
|
|
|
*p = '-';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-13 12:10:47 +03:00
|
|
|
/* Legacy options do not correspond to MachineState properties. */
|
|
|
|
if (g_str_equal(qom_name, "accel")) {
|
|
|
|
return 0;
|
|
|
|
}
|
2019-11-13 12:56:53 +03:00
|
|
|
if (g_str_equal(qom_name, "igd-passthru")) {
|
|
|
|
object_register_sugar_prop(ACCEL_CLASS_NAME("xen"), qom_name, value);
|
|
|
|
return 0;
|
|
|
|
}
|
2019-11-13 12:56:53 +03:00
|
|
|
if (g_str_equal(qom_name, "kvm-shadow-mem") ||
|
|
|
|
g_str_equal(qom_name, "kernel-irqchip")) {
|
2019-11-13 12:56:53 +03:00
|
|
|
object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), qom_name, value);
|
|
|
|
return 0;
|
|
|
|
}
|
2019-11-13 12:10:47 +03:00
|
|
|
|
2019-11-13 13:44:48 +03:00
|
|
|
return object_parse_property_opt(opaque, name, value, "type", errp);
|
|
|
|
}
|
2015-05-13 19:14:04 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2018-09-06 16:05:34 +03:00
|
|
|
static bool object_create_initial(const char *type, QemuOpts *opts)
|
2015-05-13 19:14:04 +03:00
|
|
|
{
|
2019-10-11 20:20:12 +03:00
|
|
|
if (user_creatable_print_help(type, opts)) {
|
2018-09-06 16:05:34 +03:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2019-06-04 18:12:51 +03:00
|
|
|
/*
|
|
|
|
* Objects should not be made "delayed" without a reason. If you
|
|
|
|
* add one, state the reason in a comment!
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Reason: rng-egd property "chardev" */
|
vl: Fix -drive / -blockdev persistent reservation management
qemu-system-FOO's main() acts on command line arguments in its own
idiosyncratic order. There's not much method to its madness.
Whenever we find a case where one kind of command line argument needs
to refer to something created for another kind later, we rejigger the
order.
Recent commit cda4aa9a5a "vl: Create block backends before setting
machine properties" was such a rejigger. Block backends are now
created before "delayed" objects. This broke persistent reservation
management. Reproducer:
$ qemu-system-x86_64 -object pr-manager-helper,id=pr-helper0,path=/tmp/pr-helper0.sock-drive -drive file=/dev/mapper/crypt,file.pr-manager=pr-helper0,format=raw,if=none,id=drive-scsi0-0-0-2
qemu-system-x86_64: -drive file=/dev/mapper/crypt,file.pr-manager=pr-helper0,format=raw,if=none,id=drive-scsi0-0-0-2: No persistent reservation manager with id 'pr-helper0'
The delayed pr-manager-helper object is created too late for use by
-drive or -blockdev. Normal objects are still created in time.
pr-manager-helper has always been a delayed object (commit 7c9e527659
"scsi, file-posix: add support for persistent reservation
management"). Turns out there's no real reason for that. Make it a
normal object.
Fixes: cda4aa9a5a08777cf13e164c0543bd4888b8adce
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20190604151251.9903-2-armbru@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2019-06-04 18:12:50 +03:00
|
|
|
if (g_str_equal(type, "rng-egd")) {
|
2015-05-13 19:14:04 +03:00
|
|
|
return false;
|
|
|
|
}
|
2015-10-07 06:52:21 +03:00
|
|
|
|
2018-03-01 16:46:28 +03:00
|
|
|
#if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX)
|
2019-06-04 18:12:51 +03:00
|
|
|
/* Reason: cryptodev-vhost-user property "chardev" */
|
2018-03-01 16:46:28 +03:00
|
|
|
if (g_str_equal(type, "cryptodev-vhost-user")) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-10-13 13:40:01 +03:00
|
|
|
/*
|
2019-06-04 18:12:51 +03:00
|
|
|
* Reason: filter-* property "netdev" etc.
|
2015-10-13 13:40:01 +03:00
|
|
|
*/
|
|
|
|
if (g_str_equal(type, "filter-buffer") ||
|
net/filter-mirror:Add filter-mirror
Filter-mirror is a netfilter plugin.
It gives qemu the ability to mirror
packets to a chardev.
usage:
-netdev tap,id=hn0
-chardev socket,id=mirror0,host=ip_primary,port=X,server,nowait
-filter-mirror,id=m0,netdev=hn0,queue=tx/rx/all,outdev=mirror0
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Reviewed-by: Yang Hongyang <hongyang.yang@easystack.cn>
Reviewed-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
2016-03-15 10:41:33 +03:00
|
|
|
g_str_equal(type, "filter-dump") ||
|
net/filter-mirror: implement filter-redirector
Filter-redirector is a netfilter plugin.
It gives qemu the ability to redirect net packet.
redirector can redirect filter's net packet to outdev.
and redirect indev's packet to filter.
filter
+
redirector |
+--------------+
| | |
indev +-----------+ +----------> outdev
| | |
+--------------+
|
v
filter
usage:
-netdev user,id=hn0
-chardev socket,id=s0,host=ip_primary,port=X,server,nowait
-chardev socket,id=s1,host=ip_primary,port=Y,server,nowait
-filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,indev=s0,outdev=s1
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
2016-03-17 11:16:26 +03:00
|
|
|
g_str_equal(type, "filter-mirror") ||
|
colo-compare: introduce colo compare initialization
This a COLO net ascii figure:
Primary qemu Secondary qemu
+--------------------------------------------------------------+ +----------------------------------------------------------------+
| +----------------------------------------------------------+ | | +-----------------------------------------------------------+ |
| | | | | | | |
| | guest | | | | guest | |
| | | | | | | |
| +-------^--------------------------+-----------------------+ | | +---------------------+--------+----------------------------+ |
| | | | | ^ | |
| | | | | | | |
| | +------------------------------------------------------+ | | | |
|netfilter| | | | | | netfilter | | |
| +----------+ +----------------------------+ | | | +-----------------------------------------------------------+ |
| | | | | | out | | | | | | filter excute order | |
| | | | +-----------------------------+ | | | | | | +-------------------> | |
| | | | | | | | | | | | | | TCP | |
| | +-----+--+-+ +-----v----+ +-----v----+ |pri +----+----+sec| | | | +------------+ +---+----+---v+rewriter++ +------------+ | |
| | | | | | | | |in | |in | | | | | | | | | | | | |
| | | filter | | filter | | filter +------> colo <------+ +--------> filter +--> adjust | adjust +--> filter | | |
| | | mirror | |redirector| |redirector| | | compare | | | | | | redirector | | ack | seq | | redirector | | |
| | | | | | | | | | | | | | | | | | | | | | | |
| | +----^-----+ +----+-----+ +----------+ | +---------+ | | | | +------------+ +--------+--------------+ +---+--------+ | |
| | | tx | rx rx | | | | | tx all | rx | |
| | | | | | | | +-----------------------------------------------------------+ |
| | | +--------------+ | | | | | |
| | | filter excute order | | | | | | |
| | | +----------------> | | | +--------------------------------------------------------+ |
| +-----------------------------------------+ | | |
| | | | | |
+--------------------------------------------------------------+ +----------------------------------------------------------------+
|guest receive | guest send
| |
+--------+----------------------------v------------------------+
| | NOTE: filter direction is rx/tx/all
| tap | rx:receive packets sent to the netdev
| | tx:receive packets sent by the netdev
+--------------------------------------------------------------+
In COLO-compare, we do packet comparing job.
Packets coming from the primary char indev will be sent to outdev.
Packets coming from the secondary char dev will be dropped after comparing.
colo-comapre need two input chardev and one output chardev:
primary_in=chardev1-id (source: primary send packet)
secondary_in=chardev2-id (source: secondary send packet)
outdev=chardev3-id
usage:
primary:
-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
-device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
-chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
-chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
-chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
-chardev socket,id=compare0-0,host=3.3.3.3,port=9001
-chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
-chardev socket,id=compare_out0,host=3.3.3.3,port=9005
-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
-object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out
-object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0
-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0
secondary:
-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
-device e1000,netdev=hn0,mac=52:a4:00:12:78:66
-chardev socket,id=red0,host=3.3.3.3,port=9003
-chardev socket,id=red1,host=3.3.3.3,port=9004
-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
2016-09-27 05:22:26 +03:00
|
|
|
g_str_equal(type, "filter-redirector") ||
|
filter-rewriter: introduce filter-rewriter initialization
Filter-rewriter is a part of COLO project.
It will rewrite some of secondary packet to make
secondary guest's tcp connection established successfully.
In this module we will rewrite tcp packet's ack to the secondary
from primary,and rewrite tcp packet's seq to the primary from
secondary.
usage:
colo secondary:
-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
-object filter-rewriter,id=rew0,netdev=hn0,queue=all
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
2016-09-27 05:22:32 +03:00
|
|
|
g_str_equal(type, "colo-compare") ||
|
2016-09-26 11:08:21 +03:00
|
|
|
g_str_equal(type, "filter-rewriter") ||
|
|
|
|
g_str_equal(type, "filter-replay")) {
|
2015-10-07 06:52:21 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-09-02 21:59:44 +03:00
|
|
|
/* Memory allocation by backends needs to be done
|
|
|
|
* after configure_accelerator() (due to the tcg_enabled()
|
|
|
|
* checks at memory_region_init_*()).
|
|
|
|
*
|
|
|
|
* Also, 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;
|
|
|
|
}
|
|
|
|
|
2015-05-13 19:14:04 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The remainder of object creation happens after the
|
2015-10-07 06:52:13 +03:00
|
|
|
* creation of chardev, fsdev, net clients and device data types.
|
2015-05-13 19:14:04 +03:00
|
|
|
*/
|
2018-09-06 16:05:34 +03:00
|
|
|
static bool object_create_delayed(const char *type, QemuOpts *opts)
|
2015-05-13 19:14:04 +03:00
|
|
|
{
|
2018-09-06 16:05:34 +03:00
|
|
|
return !object_create_initial(type, opts);
|
2015-05-13 19:14:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-07 08:33:57 +03:00
|
|
|
static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size,
|
|
|
|
MachineClass *mc)
|
2015-01-11 13:38:43 +03:00
|
|
|
{
|
|
|
|
uint64_t sz;
|
|
|
|
const char *mem_str;
|
2015-05-07 08:33:57 +03:00
|
|
|
const ram_addr_t default_ram_size = mc->default_ram_size;
|
2015-01-11 13:38:43 +03:00
|
|
|
QemuOpts *opts = qemu_find_opts_singleton("memory");
|
2016-02-12 22:02:27 +03:00
|
|
|
Location loc;
|
|
|
|
|
|
|
|
loc_push_none(&loc);
|
|
|
|
qemu_opts_loc_restore(opts);
|
2015-01-11 13:38:43 +03:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2018-06-25 15:42:35 +03:00
|
|
|
sz *= MiB;
|
|
|
|
if (sz / MiB != overflow_check) {
|
2015-01-11 13:38:43 +03:00
|
|
|
error_report("too large 'size' option value");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* backward compatibility behaviour for case "-m 0" */
|
|
|
|
if (sz == 0) {
|
|
|
|
sz = default_ram_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
sz = QEMU_ALIGN_UP(sz, 8192);
|
|
|
|
ram_size = sz;
|
|
|
|
if (ram_size != sz) {
|
|
|
|
error_report("ram size too large");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* store value for the future use */
|
2015-02-12 18:46:36 +03:00
|
|
|
qemu_opt_set_number(opts, "size", ram_size, &error_abort);
|
2015-01-11 13:38:43 +03:00
|
|
|
*maxram_size = ram_size;
|
|
|
|
|
2018-04-23 19:51:26 +03:00
|
|
|
if (qemu_opt_get(opts, "maxmem")) {
|
2015-01-11 13:38:43 +03:00
|
|
|
uint64_t slots;
|
|
|
|
|
|
|
|
sz = qemu_opt_get_size(opts, "maxmem", 0);
|
2015-01-29 16:48:40 +03:00
|
|
|
slots = qemu_opt_get_number(opts, "slots", 0);
|
2015-01-11 13:38:43 +03:00
|
|
|
if (sz < ram_size) {
|
2015-01-29 16:48:40 +03:00
|
|
|
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);
|
2015-01-11 13:38:43 +03:00
|
|
|
exit(EXIT_FAILURE);
|
2018-04-23 19:51:26 +03:00
|
|
|
} else if (slots && sz == ram_size) {
|
2015-01-29 16:48:40 +03:00
|
|
|
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);
|
2015-01-11 13:38:43 +03:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
*maxram_size = sz;
|
|
|
|
*ram_slots = slots;
|
2018-04-23 19:51:26 +03:00
|
|
|
} else if (qemu_opt_get(opts, "slots")) {
|
|
|
|
error_report("invalid -m option value: missing 'maxmem' option");
|
2015-01-11 13:38:43 +03:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2016-02-12 22:02:27 +03:00
|
|
|
|
|
|
|
loc_pop(&loc);
|
2015-01-11 13:38:43 +03:00
|
|
|
}
|
|
|
|
|
2016-06-15 21:54:52 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-01-17 21:00:51 +03:00
|
|
|
static int qemu_read_default_config_file(void)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = qemu_read_config_file(CONFIG_QEMU_CONFDIR "/qemu.conf");
|
|
|
|
if (ret < 0 && ret != -ENOENT) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-06-27 07:10:12 +03:00
|
|
|
static void user_register_global_props(void)
|
|
|
|
{
|
|
|
|
qemu_opts_foreach(qemu_find_opts("global"),
|
|
|
|
global_init_func, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
2019-11-13 14:37:00 +03:00
|
|
|
static int do_configure_icount(void *opaque, QemuOpts *opts, Error **errp)
|
|
|
|
{
|
|
|
|
configure_icount(opts, errp);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-11-13 12:36:01 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2019-11-14 13:10:43 +03:00
|
|
|
static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
|
|
|
|
{
|
2019-11-13 12:10:47 +03:00
|
|
|
bool *p_init_failed = opaque;
|
|
|
|
const char *acc = qemu_opt_get(opts, "accel");
|
|
|
|
AccelClass *ac = accel_find(acc);
|
2019-11-13 16:03:46 +03:00
|
|
|
AccelState *accel;
|
2019-11-13 12:10:47 +03:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!ac) {
|
2019-11-13 14:08:38 +03:00
|
|
|
*p_init_failed = true;
|
|
|
|
error_report("invalid accelerator %s", acc);
|
2019-11-13 12:10:47 +03:00
|
|
|
return 0;
|
|
|
|
}
|
2019-11-13 16:03:46 +03:00
|
|
|
accel = ACCEL(object_new_with_class(OBJECT_CLASS(ac)));
|
2019-11-13 17:16:44 +03:00
|
|
|
object_apply_compat_props(OBJECT(accel));
|
2019-11-13 12:36:01 +03:00
|
|
|
qemu_opt_foreach(opts, accelerator_set_property,
|
|
|
|
accel,
|
|
|
|
&error_fatal);
|
|
|
|
|
2019-11-13 16:03:46 +03:00
|
|
|
ret = accel_init_machine(accel, current_machine);
|
2019-11-13 12:10:47 +03:00
|
|
|
if (ret < 0) {
|
|
|
|
*p_init_failed = true;
|
|
|
|
error_report("failed to initialize %s: %s",
|
|
|
|
acc, strerror(-ret));
|
|
|
|
return 0;
|
|
|
|
}
|
2019-11-13 17:16:44 +03:00
|
|
|
|
2019-11-13 12:10:47 +03:00
|
|
|
return 1;
|
2019-11-14 13:10:43 +03:00
|
|
|
}
|
|
|
|
|
2019-11-13 11:59:04 +03:00
|
|
|
static void configure_accelerators(const char *progname)
|
2019-11-14 13:10:43 +03:00
|
|
|
{
|
2019-11-13 11:59:04 +03:00
|
|
|
const char *accel;
|
|
|
|
bool init_failed = false;
|
|
|
|
|
|
|
|
qemu_opts_foreach(qemu_find_opts("icount"),
|
|
|
|
do_configure_icount, NULL, &error_fatal);
|
|
|
|
|
|
|
|
accel = qemu_opt_get(qemu_get_machine_opts(), "accel");
|
2019-11-13 12:10:47 +03:00
|
|
|
if (QTAILQ_EMPTY(&qemu_accel_opts.head)) {
|
2020-01-09 04:14:32 +03:00
|
|
|
char **accel_list, **tmp;
|
|
|
|
|
2019-11-13 12:10:47 +03:00
|
|
|
if (accel == NULL) {
|
|
|
|
/* Select the default accelerator */
|
2020-01-09 04:07:30 +03:00
|
|
|
bool have_tcg = accel_find("tcg");
|
|
|
|
bool have_kvm = accel_find("kvm");
|
|
|
|
|
|
|
|
if (have_tcg && have_kvm) {
|
|
|
|
if (g_str_has_suffix(progname, "kvm")) {
|
2019-11-13 12:10:47 +03:00
|
|
|
/* If the program name ends with "kvm", we prefer KVM */
|
|
|
|
accel = "kvm:tcg";
|
|
|
|
} else {
|
|
|
|
accel = "tcg:kvm";
|
|
|
|
}
|
2020-01-09 04:07:30 +03:00
|
|
|
} else if (have_kvm) {
|
|
|
|
accel = "kvm";
|
|
|
|
} else if (have_tcg) {
|
|
|
|
accel = "tcg";
|
|
|
|
} else {
|
|
|
|
error_report("No accelerator selected and"
|
|
|
|
" no default accelerator available");
|
|
|
|
exit(1);
|
2019-11-13 11:59:04 +03:00
|
|
|
}
|
|
|
|
}
|
2019-11-13 12:10:47 +03:00
|
|
|
accel_list = g_strsplit(accel, ":", 0);
|
2019-11-13 11:59:04 +03:00
|
|
|
|
2020-01-09 05:10:07 +03:00
|
|
|
for (tmp = accel_list; *tmp; tmp++) {
|
2019-11-13 12:10:47 +03:00
|
|
|
/*
|
|
|
|
* Filter invalid accelerators here, to prevent obscenities
|
|
|
|
* such as "-machine accel=tcg,,thread=single".
|
|
|
|
*/
|
|
|
|
if (accel_find(*tmp)) {
|
|
|
|
qemu_opts_parse_noisily(qemu_find_opts("accel"), *tmp, true);
|
2019-11-13 14:08:38 +03:00
|
|
|
} else {
|
|
|
|
init_failed = true;
|
|
|
|
error_report("invalid accelerator %s", *tmp);
|
2019-11-13 12:10:47 +03:00
|
|
|
}
|
2019-11-13 11:59:04 +03:00
|
|
|
}
|
2020-01-08 14:42:07 +03:00
|
|
|
g_strfreev(accel_list);
|
2019-11-13 12:10:47 +03:00
|
|
|
} else {
|
|
|
|
if (accel != NULL) {
|
|
|
|
error_report("The -accel and \"-machine accel=\" options are incompatible");
|
|
|
|
exit(1);
|
2019-11-13 11:59:04 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-13 12:10:47 +03:00
|
|
|
if (!qemu_opts_foreach(qemu_find_opts("accel"),
|
|
|
|
do_configure_accelerator, &init_failed, &error_fatal)) {
|
2019-11-13 11:59:04 +03:00
|
|
|
if (!init_failed) {
|
2019-11-13 12:10:47 +03:00
|
|
|
error_report("no accelerator found");
|
2019-11-13 11:59:04 +03:00
|
|
|
}
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (init_failed) {
|
2020-01-21 14:03:48 +03:00
|
|
|
AccelClass *ac = ACCEL_GET_CLASS(current_accel());
|
2019-11-13 14:08:38 +03:00
|
|
|
error_report("falling back to %s", ac->name);
|
2019-11-13 11:59:04 +03:00
|
|
|
}
|
|
|
|
|
2019-11-14 13:10:43 +03:00
|
|
|
if (use_icount && !(tcg_enabled() || qtest_enabled())) {
|
|
|
|
error_report("-icount is not allowed with hardware virtualization");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-20 07:10:58 +03:00
|
|
|
void qemu_init(int argc, char **argv, char **envp)
|
2003-06-24 17:42:40 +04:00
|
|
|
{
|
2007-12-02 07:51:10 +03:00
|
|
|
int i;
|
net: remove broken net_set_boot_mask() boot device validation
There are many problems with net_set_boot_mask():
1) It is broken when using the device model instead of "-net nic". Example:
$ qemu-system-x86_64 -device rtl8139,vlan=0,id=net0,mac=52:54:00:82:41:fd,bus=pci.0,addr=0x4 -net user,vlan=0,name=hostnet0 -vnc 0.0.0.0:0 -boot n
Cannot boot from non-existent NIC
$
2) The mask was previously used to set which boot ROMs were supposed to be
loaded, but this was changed long time ago. Now all ROM images are loaded,
and SeaBIOS takes care of jumping to the right boot entry point depending on
the boot settings.
3) Interpretation and validation of the boot parameter letters is done on
the machine type code. Examples: PC accepts only a,b,c,d,n as valid boot
device letters. mac99 accepts only a,b,c,d,e,f.
As a side-effect of this change, qemu-kvm won't abort anymore if using "-boot n"
on a machine with no network devices. Checking if the requested boot device is
valid is now a task for the BIOS or the machine-type code.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Acked-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2010-04-07 02:22:07 +04:00
|
|
|
int snapshot, linux_boot;
|
2003-10-30 04:11:23 +03:00
|
|
|
const char *initrd_filename;
|
2003-10-01 01:07:02 +04:00
|
|
|
const char *kernel_filename, *kernel_cmdline;
|
2015-02-03 14:31:09 +03:00
|
|
|
const char *boot_order = NULL;
|
|
|
|
const char *boot_once = NULL;
|
2009-01-16 22:04:14 +03:00
|
|
|
DisplayState *ds;
|
2017-02-23 21:29:08 +03:00
|
|
|
QemuOpts *opts, *machine_opts;
|
2017-12-18 20:14:32 +03:00
|
|
|
QemuOpts *icount_opts = NULL, *accel_opts = NULL;
|
2010-08-20 15:52:02 +04:00
|
|
|
QemuOptsList *olist;
|
2004-05-14 02:02:20 +04:00
|
|
|
int optind;
|
2010-01-22 18:18:06 +03:00
|
|
|
const char *optarg;
|
2004-10-03 17:29:03 +04:00
|
|
|
const char *loadvm = NULL;
|
2014-03-05 21:30:47 +04:00
|
|
|
MachineClass *machine_class;
|
2019-04-17 05:59:40 +03:00
|
|
|
const char *cpu_option;
|
2014-03-10 18:37:40 +04:00
|
|
|
const char *vga_model = NULL;
|
2013-10-18 15:51:11 +04:00
|
|
|
const char *qtest_chrdev = NULL;
|
|
|
|
const char *qtest_log = NULL;
|
2008-10-13 07:12:02 +04:00
|
|
|
const char *incoming = NULL;
|
2012-05-02 20:07:29 +04:00
|
|
|
bool userconfig = true;
|
2016-04-19 22:55:25 +03:00
|
|
|
bool nographic = false;
|
2016-04-19 22:55:28 +03:00
|
|
|
int display_remote = 0;
|
2011-06-07 20:32:40 +04:00
|
|
|
const char *log_mask = NULL;
|
|
|
|
const char *log_file = NULL;
|
2016-01-07 16:55:24 +03:00
|
|
|
char *trace_file = NULL;
|
2015-01-11 13:38:43 +03:00
|
|
|
ram_addr_t maxram_size;
|
2014-06-02 17:25:02 +04:00
|
|
|
uint64_t ram_slots = 0;
|
2014-06-20 17:26:08 +04:00
|
|
|
FILE *vmstate_dump_file = NULL;
|
2014-09-18 15:30:49 +04:00
|
|
|
Error *main_loop_err = NULL;
|
2015-07-01 20:10:29 +03:00
|
|
|
Error *err = NULL;
|
2016-05-16 19:34:35 +03:00
|
|
|
bool list_data_dirs = false;
|
2018-01-04 19:05:14 +03:00
|
|
|
char *dir, **dirs;
|
2019-03-08 16:14:38 +03:00
|
|
|
BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
|
2017-07-24 17:28:22 +03:00
|
|
|
QemuPluginList plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list);
|
2011-02-26 21:38:39 +03:00
|
|
|
|
2019-07-16 10:21:27 +03:00
|
|
|
os_set_line_buffering();
|
|
|
|
|
log: Make glib logging go through QEMU
This commit adds a error_init() helper which calls
g_log_set_default_handler() so that glib logs (g_log, g_warning, ...)
are handled similarly to other QEMU logs. This means they will get a
timestamp if timestamps are enabled, and they will go through the
HMP monitor if one is configured.
This commit also adds a call to error_init() to the binaries
installed by QEMU. Since error_init() also calls error_set_progname(),
this means that *-linux-user, *-bsd-user and qemu-pr-helper messages
output with error_report, info_report, ... will slightly change: they
will be prefixed by the binary name.
glib debug messages are enabled through G_MESSAGES_DEBUG similarly to
the glib default log handler.
At the moment, this change will mostly impact SPICE logging if your
spice version is >= 0.14.1. With older spice versions, this is not going
to work as expected, but will not have any ill effect, so this call is
not conditional on the SPICE version.
Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20190131164614.19209-3-cfergeau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2019-01-31 19:46:14 +03:00
|
|
|
error_init(argv[0]);
|
2016-10-04 16:35:52 +03:00
|
|
|
module_call_init(MODULE_INIT_TRACE);
|
|
|
|
|
2016-08-28 04:45:14 +03:00
|
|
|
qemu_init_cpu_list();
|
2015-03-03 13:36:09 +03:00
|
|
|
qemu_init_cpu_loop();
|
2018-02-27 12:52:48 +03:00
|
|
|
|
2015-03-03 13:36:09 +03:00
|
|
|
qemu_mutex_lock_iothread();
|
|
|
|
|
2010-06-04 16:08:07 +04:00
|
|
|
atexit(qemu_run_exit_notifiers);
|
2014-02-10 10:48:51 +04:00
|
|
|
qemu_init_exec_dir(argv[0]);
|
2010-02-24 16:37:14 +03:00
|
|
|
|
2012-03-05 00:32:35 +04:00
|
|
|
module_call_init(MODULE_INIT_QOM);
|
|
|
|
|
2012-11-26 19:03:42 +04:00
|
|
|
qemu_add_opts(&qemu_drive_opts);
|
2013-11-09 08:15:47 +04:00
|
|
|
qemu_add_drive_opts(&qemu_legacy_drive_opts);
|
|
|
|
qemu_add_drive_opts(&qemu_common_drive_opts);
|
|
|
|
qemu_add_drive_opts(&qemu_drive_opts);
|
2016-10-06 12:33:17 +03:00
|
|
|
qemu_add_drive_opts(&bdrv_runtime_opts);
|
2012-11-26 19:03:42 +04:00
|
|
|
qemu_add_opts(&qemu_chardev_opts);
|
|
|
|
qemu_add_opts(&qemu_device_opts);
|
|
|
|
qemu_add_opts(&qemu_netdev_opts);
|
2018-02-21 13:18:36 +03:00
|
|
|
qemu_add_opts(&qemu_nic_opts);
|
2012-11-26 19:03:42 +04:00
|
|
|
qemu_add_opts(&qemu_net_opts);
|
|
|
|
qemu_add_opts(&qemu_rtc_opts);
|
|
|
|
qemu_add_opts(&qemu_global_opts);
|
|
|
|
qemu_add_opts(&qemu_mon_opts);
|
|
|
|
qemu_add_opts(&qemu_trace_opts);
|
2017-07-24 17:28:22 +03:00
|
|
|
qemu_plugin_add_opts();
|
2012-11-26 19:03:42 +04:00
|
|
|
qemu_add_opts(&qemu_option_rom_opts);
|
|
|
|
qemu_add_opts(&qemu_machine_opts);
|
2017-02-23 21:29:08 +03:00
|
|
|
qemu_add_opts(&qemu_accel_opts);
|
2013-11-27 04:27:35 +04:00
|
|
|
qemu_add_opts(&qemu_mem_opts);
|
vl: convert -smp to qemu_opts_parse()
This also introduces a new suboption, "cpus=",
which is the default. So after this patch,
-smp n,sockets=y
is the same as
-smp cpus=n,sockets=y
(with "cpu" being some generic thing, referring to
either cores, or threads, or sockets, as before).
We still don't validate relations between different
numbers, for example it is still possible to say
-smp 1,sockets=10
and it will be accepted to mean sockets=1.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Message-id: 1372072012-30305-1-git-send-email-mjt@msgid.tls.msk.ru
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-24 15:06:52 +04:00
|
|
|
qemu_add_opts(&qemu_smp_opts);
|
2012-11-26 19:03:42 +04:00
|
|
|
qemu_add_opts(&qemu_boot_opts);
|
|
|
|
qemu_add_opts(&qemu_add_fd_opts);
|
|
|
|
qemu_add_opts(&qemu_object_opts);
|
Support for TPM command line options
This patch adds support for TPM command line options.
The command line options supported here are
./qemu-... -tpmdev passthrough,path=<path to TPM device>,id=<id>
-device tpm-tis,tpmdev=<id>,id=<other id>
and
./qemu-... -tpmdev help
where the latter works similar to -soundhw help and shows a list of
available TPM backends (for example 'passthrough').
Using the type parameter, the backend is chosen, i.e., 'passthrough' for the
passthrough driver. The interpretation of the other parameters along
with determining whether enough parameters were provided is pushed into
the backend driver, which needs to implement the interface function
'create' and return a TPMDriverOpts structure if the VM can be started or
'NULL' if not enough or bad parameters were provided.
Monitor support for 'info tpm' has been added. It for example prints the
following:
(qemu) info tpm
TPM devices:
tpm0: model=tpm-tis
\ tpm0: type=passthrough,path=/dev/tpm0,cancel-path=/sys/devices/pnp0/00:09/cancel
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
Reviewed-by: Joel Schopp <jschopp@linux.vnet.ibm.com>
Message-id: 1361987275-26289-2-git-send-email-stefanb@linux.vnet.ibm.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-02-27 21:47:49 +04:00
|
|
|
qemu_add_opts(&qemu_tpmdev_opts);
|
2013-04-19 18:42:06 +04:00
|
|
|
qemu_add_opts(&qemu_realtime_opts);
|
2018-08-15 20:57:04 +03:00
|
|
|
qemu_add_opts(&qemu_overcommit_opts);
|
2013-07-04 07:02:46 +04:00
|
|
|
qemu_add_opts(&qemu_msg_opts);
|
2014-01-30 14:20:30 +04:00
|
|
|
qemu_add_opts(&qemu_name_opts);
|
2014-05-14 13:43:08 +04:00
|
|
|
qemu_add_opts(&qemu_numa_opts);
|
2014-07-25 13:56:28 +04:00
|
|
|
qemu_add_opts(&qemu_icount_opts);
|
2014-12-11 15:07:48 +03:00
|
|
|
qemu_add_opts(&qemu_semihosting_config_opts);
|
2015-04-29 18:21:53 +03:00
|
|
|
qemu_add_opts(&qemu_fw_cfg_opts);
|
2016-02-16 23:59:07 +03:00
|
|
|
module_call_init(MODULE_INIT_OPTS);
|
2012-11-26 19:03:42 +04:00
|
|
|
|
2011-09-05 23:36:31 +04:00
|
|
|
runstate_init();
|
2018-12-11 11:24:51 +03:00
|
|
|
precopy_infrastructure_init();
|
2018-03-12 20:20:59 +03:00
|
|
|
postcopy_infrastructure_init();
|
2018-06-08 06:55:10 +03:00
|
|
|
monitor_init_globals();
|
2011-09-05 23:36:31 +04:00
|
|
|
|
2015-07-01 20:10:29 +03:00
|
|
|
if (qcrypto_init(&err) < 0) {
|
2015-12-18 18:35:14 +03:00
|
|
|
error_reportf_err(err, "cannot initialize crypto: ");
|
2015-07-01 20:10:29 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
2009-09-15 15:36:04 +04:00
|
|
|
|
2019-06-20 20:37:07 +03:00
|
|
|
QTAILQ_INIT(&vm_change_state_head);
|
2010-06-10 13:42:21 +04:00
|
|
|
os_setup_early_signal_handling();
|
2006-06-25 20:25:21 +04:00
|
|
|
|
2019-04-17 05:59:40 +03:00
|
|
|
cpu_option = NULL;
|
2003-07-06 21:15:21 +04:00
|
|
|
snapshot = 0;
|
2004-03-15 00:44:30 +03:00
|
|
|
|
2005-11-16 01:16:05 +03:00
|
|
|
nb_nics = 0;
|
2007-09-17 12:09:54 +04:00
|
|
|
|
2013-03-21 16:07:10 +04:00
|
|
|
bdrv_init_with_whitelist();
|
|
|
|
|
2013-12-31 14:36:08 +04:00
|
|
|
autostart = 1;
|
2008-10-05 13:56:21 +04:00
|
|
|
|
2010-01-21 19:57:58 +03:00
|
|
|
/* first pass of option parsing */
|
|
|
|
optind = 1;
|
|
|
|
while (optind < argc) {
|
|
|
|
if (argv[optind][0] != '-') {
|
|
|
|
/* disk image */
|
2010-01-27 19:46:00 +03:00
|
|
|
optind++;
|
2010-01-21 19:57:58 +03:00
|
|
|
} else {
|
|
|
|
const QEMUOption *popt;
|
|
|
|
|
|
|
|
popt = lookup_opt(argc, argv, &optarg, &optind);
|
|
|
|
switch (popt->index) {
|
2012-05-02 20:07:29 +04:00
|
|
|
case QEMU_OPTION_nouserconfig:
|
|
|
|
userconfig = false;
|
|
|
|
break;
|
2010-01-21 19:57:58 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-04 06:00:24 +03:00
|
|
|
if (userconfig) {
|
2017-01-17 21:00:51 +03:00
|
|
|
if (qemu_read_default_config_file() < 0) {
|
2010-03-05 19:25:55 +03:00
|
|
|
exit(1);
|
2010-01-21 19:57:58 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* second pass of option parsing */
|
2004-05-14 02:02:20 +04:00
|
|
|
optind = 1;
|
2003-06-24 17:42:40 +04:00
|
|
|
for(;;) {
|
2004-05-14 02:02:20 +04:00
|
|
|
if (optind >= argc)
|
2003-06-24 17:42:40 +04:00
|
|
|
break;
|
2010-01-22 18:18:06 +03:00
|
|
|
if (argv[optind][0] != '-') {
|
2019-03-18 21:33:12 +03:00
|
|
|
loc_set_cmdline(argv, optind, 1);
|
2017-12-18 20:14:32 +03:00
|
|
|
drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS);
|
2004-05-14 02:02:20 +04:00
|
|
|
} else {
|
|
|
|
const QEMUOption *popt;
|
|
|
|
|
2010-01-22 18:18:06 +03:00
|
|
|
popt = lookup_opt(argc, argv, &optarg, &optind);
|
2010-03-29 23:23:52 +04:00
|
|
|
if (!(popt->arch_mask & arch_type)) {
|
2016-05-31 11:31:38 +03:00
|
|
|
error_report("Option not supported for this target");
|
2010-03-29 23:23:52 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
2004-05-14 02:02:20 +04:00
|
|
|
switch(popt->index) {
|
2007-03-05 22:44:02 +03:00
|
|
|
case QEMU_OPTION_cpu:
|
|
|
|
/* hw initialization will check this */
|
2019-04-17 05:59:40 +03:00
|
|
|
cpu_option = optarg;
|
2007-03-05 22:44:02 +03:00
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_hda:
|
|
|
|
case QEMU_OPTION_hdb:
|
2005-06-05 18:49:17 +04:00
|
|
|
case QEMU_OPTION_hdc:
|
|
|
|
case QEMU_OPTION_hdd:
|
2011-01-28 13:21:41 +03:00
|
|
|
drive_add(IF_DEFAULT, popt->index - QEMU_OPTION_hda, optarg,
|
|
|
|
HD_OPTS);
|
2003-06-30 14:03:06 +04:00
|
|
|
break;
|
block: Initial implementation of -blockdev
The new command line option -blockdev works like QMP command
blockdev-add.
The option argument may be given in JSON syntax, exactly as in QMP.
Example usage:
-blockdev '{"node-name": "foo", "driver": "raw", "file": {"driver": "file", "filename": "foo.img"} }'
The JSON argument doesn't exactly blend into the existing option
syntax, so the traditional KEY=VALUE,... syntax is also supported,
using dotted keys to do the nesting:
-blockdev node-name=foo,driver=raw,file.driver=file,file.filename=foo.img
This does not yet support lists, but that will be addressed shortly.
Note that calling qmp_blockdev_add() (say via qmp_marshal_block_add())
right away would crash. We need to stash the configuration for later
instead. This is crudely done, and bypasses QemuOpts, even though
storing configuration is what QemuOpts is for. Need to revamp option
infrastructure to support QAPI types like BlockdevOptions.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1488317230-26248-22-git-send-email-armbru@redhat.com>
2017-03-01 00:27:07 +03:00
|
|
|
case QEMU_OPTION_blockdev:
|
|
|
|
{
|
|
|
|
Visitor *v;
|
2019-03-08 16:14:38 +03:00
|
|
|
BlockdevOptionsQueueEntry *bdo;
|
block: Initial implementation of -blockdev
The new command line option -blockdev works like QMP command
blockdev-add.
The option argument may be given in JSON syntax, exactly as in QMP.
Example usage:
-blockdev '{"node-name": "foo", "driver": "raw", "file": {"driver": "file", "filename": "foo.img"} }'
The JSON argument doesn't exactly blend into the existing option
syntax, so the traditional KEY=VALUE,... syntax is also supported,
using dotted keys to do the nesting:
-blockdev node-name=foo,driver=raw,file.driver=file,file.filename=foo.img
This does not yet support lists, but that will be addressed shortly.
Note that calling qmp_blockdev_add() (say via qmp_marshal_block_add())
right away would crash. We need to stash the configuration for later
instead. This is crudely done, and bypasses QemuOpts, even though
storing configuration is what QemuOpts is for. Need to revamp option
infrastructure to support QAPI types like BlockdevOptions.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1488317230-26248-22-git-send-email-armbru@redhat.com>
2017-03-01 00:27:07 +03:00
|
|
|
|
2018-12-13 20:58:07 +03:00
|
|
|
v = qobject_input_visitor_new_str(optarg, "driver",
|
|
|
|
&error_fatal);
|
block: Initial implementation of -blockdev
The new command line option -blockdev works like QMP command
blockdev-add.
The option argument may be given in JSON syntax, exactly as in QMP.
Example usage:
-blockdev '{"node-name": "foo", "driver": "raw", "file": {"driver": "file", "filename": "foo.img"} }'
The JSON argument doesn't exactly blend into the existing option
syntax, so the traditional KEY=VALUE,... syntax is also supported,
using dotted keys to do the nesting:
-blockdev node-name=foo,driver=raw,file.driver=file,file.filename=foo.img
This does not yet support lists, but that will be addressed shortly.
Note that calling qmp_blockdev_add() (say via qmp_marshal_block_add())
right away would crash. We need to stash the configuration for later
instead. This is crudely done, and bypasses QemuOpts, even though
storing configuration is what QemuOpts is for. Need to revamp option
infrastructure to support QAPI types like BlockdevOptions.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1488317230-26248-22-git-send-email-armbru@redhat.com>
2017-03-01 00:27:07 +03:00
|
|
|
|
2019-03-08 16:14:38 +03:00
|
|
|
bdo = g_new(BlockdevOptionsQueueEntry, 1);
|
block: Initial implementation of -blockdev
The new command line option -blockdev works like QMP command
blockdev-add.
The option argument may be given in JSON syntax, exactly as in QMP.
Example usage:
-blockdev '{"node-name": "foo", "driver": "raw", "file": {"driver": "file", "filename": "foo.img"} }'
The JSON argument doesn't exactly blend into the existing option
syntax, so the traditional KEY=VALUE,... syntax is also supported,
using dotted keys to do the nesting:
-blockdev node-name=foo,driver=raw,file.driver=file,file.filename=foo.img
This does not yet support lists, but that will be addressed shortly.
Note that calling qmp_blockdev_add() (say via qmp_marshal_block_add())
right away would crash. We need to stash the configuration for later
instead. This is crudely done, and bypasses QemuOpts, even though
storing configuration is what QemuOpts is for. Need to revamp option
infrastructure to support QAPI types like BlockdevOptions.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1488317230-26248-22-git-send-email-armbru@redhat.com>
2017-03-01 00:27:07 +03:00
|
|
|
visit_type_BlockdevOptions(v, NULL, &bdo->bdo,
|
|
|
|
&error_fatal);
|
|
|
|
visit_free(v);
|
|
|
|
loc_save(&bdo->loc);
|
|
|
|
QSIMPLEQ_INSERT_TAIL(&bdo_queue, bdo, entry);
|
|
|
|
break;
|
|
|
|
}
|
2007-12-02 07:51:10 +03:00
|
|
|
case QEMU_OPTION_drive:
|
exit if -drive specified is invalid instead of ignoring the "wrong" -drive
This fixes the problem when qemu continues even if -drive specification
is somehow invalid, resulting in a mess. Applicable for both current
master and for stable-0.14 (and the same issue exist 0.13 and 0.12 too).
The prob can actually be seriuos: when you start guest with two drives
and make an error in the specification of one of them, and the guest
has something like a raid array on the two drives, guest may start failing
that array or kick "missing" drives which may result in a mess - this is
what actually happened to me, I did't want a resync at all, and a resync
resulted in re-writing (and allocating) a 4TB virtual drive I used for
testing, which in turn resulted in my filesystem filling up and whole
thing failing badly. Yes it was just testing VM, I experimented with
larger raid arrays, but the end result was quite, well, unexpected.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-03-30 16:31:05 +04:00
|
|
|
if (drive_def(optarg) == NULL) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2015-01-11 13:56:51 +03:00
|
|
|
break;
|
2009-07-31 14:25:36 +04:00
|
|
|
case QEMU_OPTION_set:
|
|
|
|
if (qemu_set_option(optarg) != 0)
|
|
|
|
exit(1);
|
2015-01-11 13:56:51 +03:00
|
|
|
break;
|
2009-12-08 15:11:34 +03:00
|
|
|
case QEMU_OPTION_global:
|
|
|
|
if (qemu_global_option(optarg) != 0)
|
|
|
|
exit(1);
|
2015-01-11 13:56:51 +03:00
|
|
|
break;
|
2007-04-30 06:09:25 +04:00
|
|
|
case QEMU_OPTION_mtdblock:
|
2011-01-28 13:21:41 +03:00
|
|
|
drive_add(IF_MTD, -1, optarg, MTD_OPTS);
|
2007-04-30 06:09:25 +04:00
|
|
|
break;
|
2007-04-06 20:49:48 +04:00
|
|
|
case QEMU_OPTION_sd:
|
2013-02-28 22:23:14 +04:00
|
|
|
drive_add(IF_SD, -1, optarg, SD_OPTS);
|
2007-04-06 20:49:48 +04:00
|
|
|
break;
|
2007-04-24 10:52:59 +04:00
|
|
|
case QEMU_OPTION_pflash:
|
2011-01-28 13:21:41 +03:00
|
|
|
drive_add(IF_PFLASH, -1, optarg, PFLASH_OPTS);
|
2007-04-24 10:52:59 +04:00
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_snapshot:
|
2019-09-17 14:57:56 +03:00
|
|
|
{
|
|
|
|
Error *blocker = NULL;
|
|
|
|
snapshot = 1;
|
|
|
|
error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED,
|
|
|
|
"-snapshot");
|
|
|
|
replay_add_blocker(blocker);
|
|
|
|
}
|
2003-07-06 21:15:21 +04:00
|
|
|
break;
|
2009-04-22 02:30:27 +04:00
|
|
|
case QEMU_OPTION_numa:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("numa"),
|
|
|
|
optarg, true);
|
2014-05-14 13:43:08 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2009-04-22 02:30:27 +04:00
|
|
|
break;
|
2011-03-16 15:33:31 +03:00
|
|
|
case QEMU_OPTION_display:
|
2018-02-02 14:10:22 +03:00
|
|
|
parse_display(optarg);
|
2011-03-16 15:33:31 +03:00
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_nographic:
|
2016-04-19 22:55:25 +03:00
|
|
|
olist = qemu_find_opts("machine");
|
|
|
|
qemu_opts_parse_noisily(olist, "graphics=off", false);
|
|
|
|
nographic = true;
|
2018-02-02 14:10:14 +03:00
|
|
|
dpy.type = DISPLAY_TYPE_NONE;
|
2003-10-01 01:07:02 +04:00
|
|
|
break;
|
2008-02-10 19:33:14 +03:00
|
|
|
case QEMU_OPTION_curses:
|
2011-03-16 15:33:35 +03:00
|
|
|
#ifdef CONFIG_CURSES
|
2018-02-02 14:10:18 +03:00
|
|
|
dpy.type = DISPLAY_TYPE_CURSES;
|
2011-03-16 15:33:35 +03:00
|
|
|
#else
|
2019-03-11 16:51:26 +03:00
|
|
|
error_report("curses or iconv support is disabled");
|
2011-03-16 15:33:35 +03:00
|
|
|
exit(1);
|
2008-02-10 19:33:14 +03:00
|
|
|
#endif
|
2011-03-16 15:33:35 +03:00
|
|
|
break;
|
2007-04-30 05:48:07 +04:00
|
|
|
case QEMU_OPTION_portrait:
|
2011-06-17 14:04:36 +04:00
|
|
|
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) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("only 90, 180, 270 deg rotation is available");
|
2011-06-17 14:04:36 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
2007-04-30 05:48:07 +04:00
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_kernel:
|
2015-02-12 19:07:34 +03:00
|
|
|
qemu_opts_set(qemu_find_opts("machine"), 0, "kernel", optarg,
|
|
|
|
&error_abort);
|
2012-02-08 09:41:39 +04:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_initrd:
|
2015-02-12 19:07:34 +03:00
|
|
|
qemu_opts_set(qemu_find_opts("machine"), 0, "initrd", optarg,
|
|
|
|
&error_abort);
|
2003-10-01 01:07:02 +04:00
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_append:
|
2015-02-12 19:07:34 +03:00
|
|
|
qemu_opts_set(qemu_find_opts("machine"), 0, "append", optarg,
|
|
|
|
&error_abort);
|
2003-08-11 01:52:11 +04:00
|
|
|
break;
|
2012-03-02 15:56:38 +04:00
|
|
|
case QEMU_OPTION_dtb:
|
2015-02-12 19:07:34 +03:00
|
|
|
qemu_opts_set(qemu_find_opts("machine"), 0, "dtb", optarg,
|
|
|
|
&error_abort);
|
2012-03-02 15:56:38 +04:00
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_cdrom:
|
2011-01-28 13:21:41 +03:00
|
|
|
drive_add(IF_DEFAULT, 2, optarg, CDROM_OPTS);
|
2003-11-11 16:36:08 +03:00
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_boot:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("boot-opts"),
|
|
|
|
optarg, true);
|
vl: Fix -boot order and once regressions, and related bugs
Option "once" sets up a different boot order just for the initial
boot. Boot order reverts back to normal on reset. Option "order"
changes the normal boot order.
The reversal is implemented by reset handler restore_boot_devices(),
which takes the boot order to revert to as argument.
restore_boot_devices() does nothing on its first call, because that
must be the initial machine reset. On its second call, it changes the
boot order back, and unregisters itself.
Because we register the handler right when -boot gets parsed, we can
revert to an incorrect normal boot order, and multiple -boot can
interact in funny ways.
Here's how things work without -boot once or order:
* boot_devices is "".
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "". machine->init() configures firmware
accordingly. For PC machines, machine->boot_order is "cad", and
pc_cmos_init() writes it to RTC CMOS, where SeaBIOS picks it up.
Now consider -boot order=:
* boot_devices is "".
* -boot order= sets boot_devices to "" (no change).
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "", as above.
Bug: -boot order= has no effect. Broken in commit e4ada29e.
Next, consider -boot once=a:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* main() passes boot_devices "a" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "a".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of machine->boot_order. The
actual boot order depends on how firmware interprets "". Broken
in commit e4ada29e.
Next, consider -boot once=a -boot order=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot order=c sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "c".
Bug: it should be "a". I figure this has always been broken.
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of "c". I figure this has
always been broken, just differently broken before commit
e4ada29e.
Next, consider -boot once=a -boot once=b -boot once=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot once=b registers restore_boot_devices() with argument "a", and
sets boot_devices to "b".
* -boot once=c registers restore_boot_devices() with argument "b", and
sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
- restore_boot_devices() gets called with argument "a". Calls
qemu_boot_set("a") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
- restore_boot_devices() gets called with argument "b". Calls
qemu_boot_set("b") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
* Machine boots, boot order is "b".
Bug: should really be "c", because that came last, and for all other
-boot options, the last one wins. I figure this was broken some
time before commit 37905d6a, and fixed there only for a single
occurence of "once".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Same bug as above: boot order reverts to "" instead of
machine->boot_order.
Fix by acting upon -boot options order, once and menu only after
option parsing is complete, and the machine is known. This is how the
other -boot options work already.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1371208516-7857-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-14 15:15:03 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
2003-11-11 16:36:08 +03:00
|
|
|
}
|
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_fda:
|
|
|
|
case QEMU_OPTION_fdb:
|
2011-01-28 13:21:41 +03:00
|
|
|
drive_add(IF_FLOPPY, popt->index - QEMU_OPTION_fda,
|
|
|
|
optarg, FD_OPTS);
|
2004-01-05 03:02:06 +03:00
|
|
|
break;
|
2006-06-14 20:03:05 +04:00
|
|
|
case QEMU_OPTION_no_fd_bootchk:
|
|
|
|
fd_bootchk = 0;
|
|
|
|
break;
|
2009-10-08 22:58:26 +04:00
|
|
|
case QEMU_OPTION_netdev:
|
2016-05-12 17:17:16 +03:00
|
|
|
default_net = 0;
|
2010-08-20 15:52:01 +04:00
|
|
|
if (net_client_parse(qemu_find_opts("netdev"), optarg) == -1) {
|
2009-10-08 22:58:26 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2018-02-21 13:18:36 +03:00
|
|
|
case QEMU_OPTION_nic:
|
|
|
|
default_net = 0;
|
|
|
|
if (net_client_parse(qemu_find_opts("nic"), optarg) == -1) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2005-11-16 01:16:05 +03:00
|
|
|
case QEMU_OPTION_net:
|
2016-05-12 17:17:16 +03:00
|
|
|
default_net = 0;
|
2010-08-20 15:52:01 +04:00
|
|
|
if (net_client_parse(qemu_find_opts("net"), optarg) == -1) {
|
2004-03-15 00:44:30 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
2004-04-03 01:21:32 +04:00
|
|
|
break;
|
2012-01-26 02:39:02 +04:00
|
|
|
#ifdef CONFIG_LIBISCSI
|
|
|
|
case QEMU_OPTION_iscsi:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("iscsi"),
|
|
|
|
optarg, false);
|
2012-01-26 02:39:02 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2004-08-25 01:57:12 +04:00
|
|
|
#endif
|
2005-10-30 21:58:22 +03:00
|
|
|
case QEMU_OPTION_audio_help:
|
2019-03-09 01:34:15 +03:00
|
|
|
audio_legacy_help();
|
2005-10-30 21:58:22 +03:00
|
|
|
exit (0);
|
|
|
|
break;
|
2019-03-09 01:34:15 +03:00
|
|
|
case QEMU_OPTION_audiodev:
|
|
|
|
audio_parse_option(optarg);
|
|
|
|
break;
|
2005-10-30 21:58:22 +03:00
|
|
|
case QEMU_OPTION_soundhw:
|
|
|
|
select_soundhw (optarg);
|
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_h:
|
2007-06-30 03:26:08 +04:00
|
|
|
help(0);
|
2004-05-14 02:02:20 +04:00
|
|
|
break;
|
2009-04-08 02:58:45 +04:00
|
|
|
case QEMU_OPTION_version:
|
|
|
|
version();
|
|
|
|
exit(0);
|
|
|
|
break;
|
2015-01-11 13:38:43 +03:00
|
|
|
case QEMU_OPTION_m:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("memory"),
|
|
|
|
optarg, true);
|
2013-11-27 04:27:35 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2004-05-14 02:02:20 +04:00
|
|
|
break;
|
Support for TPM command line options
This patch adds support for TPM command line options.
The command line options supported here are
./qemu-... -tpmdev passthrough,path=<path to TPM device>,id=<id>
-device tpm-tis,tpmdev=<id>,id=<other id>
and
./qemu-... -tpmdev help
where the latter works similar to -soundhw help and shows a list of
available TPM backends (for example 'passthrough').
Using the type parameter, the backend is chosen, i.e., 'passthrough' for the
passthrough driver. The interpretation of the other parameters along
with determining whether enough parameters were provided is pushed into
the backend driver, which needs to implement the interface function
'create' and return a TPMDriverOpts structure if the VM can be started or
'NULL' if not enough or bad parameters were provided.
Monitor support for 'info tpm' has been added. It for example prints the
following:
(qemu) info tpm
TPM devices:
tpm0: model=tpm-tis
\ tpm0: type=passthrough,path=/dev/tpm0,cancel-path=/sys/devices/pnp0/00:09/cancel
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
Reviewed-by: Joel Schopp <jschopp@linux.vnet.ibm.com>
Message-id: 1361987275-26289-2-git-send-email-stefanb@linux.vnet.ibm.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-02-27 21:47:49 +04:00
|
|
|
#ifdef CONFIG_TPM
|
|
|
|
case QEMU_OPTION_tpmdev:
|
|
|
|
if (tpm_config_parse(qemu_find_opts("tpmdev"), optarg) < 0) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
2010-03-02 02:25:08 +03:00
|
|
|
case QEMU_OPTION_mempath:
|
|
|
|
mem_path = optarg;
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_mem_prealloc:
|
|
|
|
mem_prealloc = 1;
|
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_d:
|
2011-06-07 20:32:40 +04:00
|
|
|
log_mask = optarg;
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_D:
|
|
|
|
log_file = optarg;
|
2004-05-14 02:02:20 +04:00
|
|
|
break;
|
2016-03-15 17:30:20 +03:00
|
|
|
case QEMU_OPTION_DFILTER:
|
2016-06-15 20:27:15 +03:00
|
|
|
qemu_set_dfilter_ranges(optarg, &error_fatal);
|
2016-03-15 17:30:20 +03:00
|
|
|
break;
|
2019-03-14 23:06:29 +03:00
|
|
|
case QEMU_OPTION_seed:
|
|
|
|
qemu_guest_random_seed_main(optarg, &error_fatal);
|
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_s:
|
2012-02-07 18:09:13 +04:00
|
|
|
add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT);
|
2004-05-14 02:02:20 +04:00
|
|
|
break;
|
2009-04-05 22:43:41 +04:00
|
|
|
case QEMU_OPTION_gdb:
|
2012-02-07 18:09:13 +04:00
|
|
|
add_device_config(DEV_GDB, optarg);
|
2004-05-14 02:02:20 +04:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_L:
|
2016-05-16 19:34:35 +03:00
|
|
|
if (is_help_option(optarg)) {
|
|
|
|
list_data_dirs = true;
|
2017-09-14 14:42:35 +03:00
|
|
|
} else {
|
|
|
|
qemu_add_data_dir(optarg);
|
2013-03-08 14:42:24 +04:00
|
|
|
}
|
2004-05-14 02:02:20 +04:00
|
|
|
break;
|
2007-10-05 17:08:35 +04:00
|
|
|
case QEMU_OPTION_bios:
|
2015-02-12 19:07:34 +03:00
|
|
|
qemu_opts_set(qemu_find_opts("machine"), 0, "firmware", optarg,
|
|
|
|
&error_abort);
|
2007-10-05 17:08:35 +04:00
|
|
|
break;
|
2009-04-06 00:08:59 +04:00
|
|
|
case QEMU_OPTION_singlestep:
|
|
|
|
singlestep = 1;
|
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_S:
|
2007-01-21 19:47:01 +03:00
|
|
|
autostart = 0;
|
2004-05-14 02:02:20 +04:00
|
|
|
break;
|
2015-01-11 13:56:51 +03:00
|
|
|
case QEMU_OPTION_k:
|
|
|
|
keyboard_layout = optarg;
|
|
|
|
break;
|
2008-09-28 04:42:05 +04:00
|
|
|
case QEMU_OPTION_vga:
|
2011-09-27 23:15:42 +04:00
|
|
|
vga_model = optarg;
|
2012-05-10 11:39:17 +04:00
|
|
|
default_vga = 0;
|
2004-07-09 01:17:50 +04:00
|
|
|
break;
|
2004-06-21 20:46:10 +04:00
|
|
|
case QEMU_OPTION_g:
|
|
|
|
{
|
|
|
|
const char *p;
|
|
|
|
int w, h, depth;
|
|
|
|
p = optarg;
|
|
|
|
w = strtol(p, (char **)&p, 10);
|
|
|
|
if (w <= 0) {
|
|
|
|
graphic_error:
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("invalid resolution or depth");
|
2004-06-21 20:46:10 +04:00
|
|
|
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);
|
2019-10-26 19:45:43 +03:00
|
|
|
if (depth != 1 && depth != 2 && depth != 4 &&
|
|
|
|
depth != 8 && depth != 15 && depth != 16 &&
|
2004-06-21 20:46:10 +04:00
|
|
|
depth != 24 && depth != 32)
|
|
|
|
goto graphic_error;
|
|
|
|
} else if (*p == '\0') {
|
|
|
|
depth = graphic_depth;
|
|
|
|
} else {
|
|
|
|
goto graphic_error;
|
|
|
|
}
|
2007-09-17 12:09:54 +04:00
|
|
|
|
2004-06-21 20:46:10 +04:00
|
|
|
graphic_width = w;
|
|
|
|
graphic_height = h;
|
|
|
|
graphic_depth = depth;
|
|
|
|
}
|
|
|
|
break;
|
2007-02-18 20:04:49 +03:00
|
|
|
case QEMU_OPTION_echr:
|
|
|
|
{
|
|
|
|
char *r;
|
|
|
|
term_escape_char = strtol(optarg, &r, 0);
|
|
|
|
if (r == optarg)
|
|
|
|
printf("Bad argument to echr\n");
|
|
|
|
break;
|
|
|
|
}
|
2004-07-14 21:28:13 +04:00
|
|
|
case QEMU_OPTION_monitor:
|
2009-12-08 15:11:52 +03:00
|
|
|
default_monitor = 0;
|
2013-05-16 20:02:55 +04:00
|
|
|
if (strncmp(optarg, "none", 4)) {
|
2014-11-17 15:31:04 +03:00
|
|
|
monitor_parse(optarg, "readline", false);
|
2013-05-16 20:02:55 +04:00
|
|
|
}
|
2009-12-08 15:11:52 +03:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_qmp:
|
2014-11-17 15:31:04 +03:00
|
|
|
monitor_parse(optarg, "control", false);
|
|
|
|
default_monitor = 0;
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_qmp_pretty:
|
|
|
|
monitor_parse(optarg, "control", true);
|
2010-03-21 22:14:38 +03:00
|
|
|
default_monitor = 0;
|
2004-07-14 21:28:13 +04:00
|
|
|
break;
|
2009-12-08 15:11:51 +03:00
|
|
|
case QEMU_OPTION_mon:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("mon"), optarg,
|
|
|
|
true);
|
2009-12-08 15:11:51 +03:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2010-03-21 22:14:38 +03:00
|
|
|
default_monitor = 0;
|
2009-12-08 15:11:51 +03:00
|
|
|
break;
|
2009-09-10 12:58:35 +04:00
|
|
|
case QEMU_OPTION_chardev:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
|
|
|
|
optarg, true);
|
2009-09-10 12:58:35 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2010-04-29 16:14:43 +04:00
|
|
|
case QEMU_OPTION_fsdev:
|
2010-08-20 15:52:02 +04:00
|
|
|
olist = qemu_find_opts("fsdev");
|
|
|
|
if (!olist) {
|
2015-10-30 18:08:02 +03:00
|
|
|
error_report("fsdev support is disabled");
|
2010-08-20 15:52:02 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(olist, optarg, true);
|
2010-04-29 16:14:43 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
virtio-9p: Create a syntactic shortcut for the file-system pass-thru
Currently the commandline to create a virtual-filesystem pass-through between
the guest and the host is as follows:
#qemu -fsdev fstype,id=ID,path=path/to/share \
-device virtio-9p-pci,fsdev=ID,mount_tag=tag \
This patch provides a syntactic short-cut to achieve the same as follows:
#qemu -virtfs fstype,path=path/to/share,mount_tag=tag
This will be internally expanded as:
#qemu -fsdev fstype,id=tag,path=path/to/share, \
-device virtio-9p-pci,fsdev=tag,mount_tag=tag \
Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-04-29 16:15:03 +04:00
|
|
|
case QEMU_OPTION_virtfs: {
|
2011-03-16 11:31:43 +03:00
|
|
|
QemuOpts *fsdev;
|
|
|
|
QemuOpts *device;
|
2019-10-10 12:36:05 +03:00
|
|
|
const char *writeout, *sock_fd, *socket, *path, *security_model,
|
|
|
|
*multidevs;
|
virtio-9p: Create a syntactic shortcut for the file-system pass-thru
Currently the commandline to create a virtual-filesystem pass-through between
the guest and the host is as follows:
#qemu -fsdev fstype,id=ID,path=path/to/share \
-device virtio-9p-pci,fsdev=ID,mount_tag=tag \
This patch provides a syntactic short-cut to achieve the same as follows:
#qemu -virtfs fstype,path=path/to/share,mount_tag=tag
This will be internally expanded as:
#qemu -fsdev fstype,id=tag,path=path/to/share, \
-device virtio-9p-pci,fsdev=tag,mount_tag=tag \
Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-04-29 16:15:03 +04:00
|
|
|
|
2010-08-20 15:52:02 +04:00
|
|
|
olist = qemu_find_opts("virtfs");
|
|
|
|
if (!olist) {
|
2015-10-30 18:08:02 +03:00
|
|
|
error_report("virtfs support is disabled");
|
2010-08-20 15:52:02 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(olist, optarg, true);
|
virtio-9p: Create a syntactic shortcut for the file-system pass-thru
Currently the commandline to create a virtual-filesystem pass-through between
the guest and the host is as follows:
#qemu -fsdev fstype,id=ID,path=path/to/share \
-device virtio-9p-pci,fsdev=ID,mount_tag=tag \
This patch provides a syntactic short-cut to achieve the same as follows:
#qemu -virtfs fstype,path=path/to/share,mount_tag=tag
This will be internally expanded as:
#qemu -fsdev fstype,id=tag,path=path/to/share, \
-device virtio-9p-pci,fsdev=tag,mount_tag=tag \
Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-04-29 16:15:03 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2011-10-13 10:58:04 +04:00
|
|
|
if (qemu_opt_get(opts, "fsdriver") == NULL ||
|
2011-12-14 12:18:59 +04:00
|
|
|
qemu_opt_get(opts, "mount_tag") == NULL) {
|
2015-10-30 18:07:54 +03:00
|
|
|
error_report("Usage: -virtfs fsdriver,mount_tag=tag");
|
2010-06-15 00:34:40 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
2011-03-16 11:31:43 +03:00
|
|
|
fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
|
virtfs: allow a device id to be specified in the -virtfs option
When using a virtfs root filesystem, the mount_tag needs to be set to
/dev/root. This can be done long-hand as
-fsdev local,id=root,path=/path/to/rootfs,...
-device virtio-9p-pci,fsdev=root,mount_tag=/dev/root
but the -virtfs shortcut cannot be used as it hard-codes the device identifier
to match the mount_tag, and device identifiers may not contain '/':
$ qemu-system-x86_64 -virtfs local,path=/foo,mount_tag=/dev/root,security_model=passthrough
qemu-system-x86_64: -virtfs local,path=/foo,mount_tag=/dev/root,security_model=passthrough: duplicate fsdev id: /dev/root
To support this case using -virtfs, we allow the device identifier to be
specified explicitly when the mount_tag is not suitable:
-virtfs local,id=root,path=/path/to/rootfs,mount_tag=/dev/root,...
Signed-off-by: Chris Webb <chris@arachsys.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2011-11-24 21:05:18 +04:00
|
|
|
qemu_opts_id(opts) ?:
|
2012-03-20 22:51:57 +04:00
|
|
|
qemu_opt_get(opts, "mount_tag"),
|
|
|
|
1, NULL);
|
2011-03-16 11:31:43 +03:00
|
|
|
if (!fsdev) {
|
virtfs: allow a device id to be specified in the -virtfs option
When using a virtfs root filesystem, the mount_tag needs to be set to
/dev/root. This can be done long-hand as
-fsdev local,id=root,path=/path/to/rootfs,...
-device virtio-9p-pci,fsdev=root,mount_tag=/dev/root
but the -virtfs shortcut cannot be used as it hard-codes the device identifier
to match the mount_tag, and device identifiers may not contain '/':
$ qemu-system-x86_64 -virtfs local,path=/foo,mount_tag=/dev/root,security_model=passthrough
qemu-system-x86_64: -virtfs local,path=/foo,mount_tag=/dev/root,security_model=passthrough: duplicate fsdev id: /dev/root
To support this case using -virtfs, we allow the device identifier to be
specified explicitly when the mount_tag is not suitable:
-virtfs local,id=root,path=/path/to/rootfs,mount_tag=/dev/root,...
Signed-off-by: Chris Webb <chris@arachsys.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2011-11-24 21:05:18 +04:00
|
|
|
error_report("duplicate or invalid fsdev id: %s",
|
2015-10-30 18:07:52 +03:00
|
|
|
qemu_opt_get(opts, "mount_tag"));
|
virtio-9p: Create a syntactic shortcut for the file-system pass-thru
Currently the commandline to create a virtual-filesystem pass-through between
the guest and the host is as follows:
#qemu -fsdev fstype,id=ID,path=path/to/share \
-device virtio-9p-pci,fsdev=ID,mount_tag=tag \
This patch provides a syntactic short-cut to achieve the same as follows:
#qemu -virtfs fstype,path=path/to/share,mount_tag=tag
This will be internally expanded as:
#qemu -fsdev fstype,id=tag,path=path/to/share, \
-device virtio-9p-pci,fsdev=tag,mount_tag=tag \
Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-04-29 16:15:03 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
2011-10-12 17:41:23 +04:00
|
|
|
|
|
|
|
writeout = qemu_opt_get(opts, "writeout");
|
|
|
|
if (writeout) {
|
|
|
|
#ifdef CONFIG_SYNC_FILE_RANGE
|
2015-02-12 19:52:20 +03:00
|
|
|
qemu_opt_set(fsdev, "writeout", writeout, &error_abort);
|
2011-10-12 17:41:23 +04:00
|
|
|
#else
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("writeout=immediate not supported "
|
|
|
|
"on this platform");
|
2011-10-12 17:41:23 +04:00
|
|
|
exit(1);
|
|
|
|
#endif
|
|
|
|
}
|
2015-02-12 19:52:20 +03:00
|
|
|
qemu_opt_set(fsdev, "fsdriver",
|
|
|
|
qemu_opt_get(opts, "fsdriver"), &error_abort);
|
2017-09-04 10:59:01 +03:00
|
|
|
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);
|
|
|
|
}
|
2011-12-14 12:28:47 +04:00
|
|
|
socket = qemu_opt_get(opts, "socket");
|
|
|
|
if (socket) {
|
2015-02-12 19:52:20 +03:00
|
|
|
qemu_opt_set(fsdev, "socket", socket, &error_abort);
|
2011-12-14 12:28:47 +04:00
|
|
|
}
|
2011-12-14 12:19:28 +04:00
|
|
|
sock_fd = qemu_opt_get(opts, "sock_fd");
|
|
|
|
if (sock_fd) {
|
2015-02-12 19:52:20 +03:00
|
|
|
qemu_opt_set(fsdev, "sock_fd", sock_fd, &error_abort);
|
2011-12-14 12:19:28 +04:00
|
|
|
}
|
2011-03-16 11:31:43 +03:00
|
|
|
|
2011-10-25 10:40:39 +04:00
|
|
|
qemu_opt_set_bool(fsdev, "readonly",
|
2015-02-12 18:37:44 +03:00
|
|
|
qemu_opt_get_bool(opts, "readonly", 0),
|
|
|
|
&error_abort);
|
2019-10-10 12:36:05 +03:00
|
|
|
multidevs = qemu_opt_get(opts, "multidevs");
|
|
|
|
if (multidevs) {
|
|
|
|
qemu_opt_set(fsdev, "multidevs", multidevs, &error_abort);
|
|
|
|
}
|
2014-01-02 06:49:17 +04:00
|
|
|
device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
|
|
|
|
&error_abort);
|
2015-02-12 19:52:20 +03:00
|
|
|
qemu_opt_set(device, "driver", "virtio-9p-pci", &error_abort);
|
2011-03-16 11:31:43 +03:00
|
|
|
qemu_opt_set(device, "fsdev",
|
virtfs: allow a device id to be specified in the -virtfs option
When using a virtfs root filesystem, the mount_tag needs to be set to
/dev/root. This can be done long-hand as
-fsdev local,id=root,path=/path/to/rootfs,...
-device virtio-9p-pci,fsdev=root,mount_tag=/dev/root
but the -virtfs shortcut cannot be used as it hard-codes the device identifier
to match the mount_tag, and device identifiers may not contain '/':
$ qemu-system-x86_64 -virtfs local,path=/foo,mount_tag=/dev/root,security_model=passthrough
qemu-system-x86_64: -virtfs local,path=/foo,mount_tag=/dev/root,security_model=passthrough: duplicate fsdev id: /dev/root
To support this case using -virtfs, we allow the device identifier to be
specified explicitly when the mount_tag is not suitable:
-virtfs local,id=root,path=/path/to/rootfs,mount_tag=/dev/root,...
Signed-off-by: Chris Webb <chris@arachsys.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2011-11-24 21:05:18 +04:00
|
|
|
qemu_opts_id(fsdev), &error_abort);
|
2011-03-16 11:31:43 +03:00
|
|
|
qemu_opt_set(device, "mount_tag",
|
2015-02-12 19:52:20 +03:00
|
|
|
qemu_opt_get(opts, "mount_tag"), &error_abort);
|
virtio-9p: Create a syntactic shortcut for the file-system pass-thru
Currently the commandline to create a virtual-filesystem pass-through between
the guest and the host is as follows:
#qemu -fsdev fstype,id=ID,path=path/to/share \
-device virtio-9p-pci,fsdev=ID,mount_tag=tag \
This patch provides a syntactic short-cut to achieve the same as follows:
#qemu -virtfs fstype,path=path/to/share,mount_tag=tag
This will be internally expanded as:
#qemu -fsdev fstype,id=tag,path=path/to/share, \
-device virtio-9p-pci,fsdev=tag,mount_tag=tag \
Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-04-29 16:15:03 +04:00
|
|
|
break;
|
|
|
|
}
|
2004-07-14 21:28:13 +04:00
|
|
|
case QEMU_OPTION_serial:
|
2009-12-08 15:11:41 +03:00
|
|
|
add_device_config(DEV_SERIAL, optarg);
|
|
|
|
default_serial = 0;
|
2010-03-07 13:28:40 +03:00
|
|
|
if (strncmp(optarg, "mon:", 4) == 0) {
|
|
|
|
default_monitor = 0;
|
|
|
|
}
|
2004-07-14 21:28:13 +04:00
|
|
|
break;
|
2009-04-25 16:56:19 +04:00
|
|
|
case QEMU_OPTION_watchdog:
|
2009-08-21 12:31:34 +04:00
|
|
|
if (watchdog) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("only one watchdog option may be given");
|
2020-02-20 07:10:58 +03:00
|
|
|
exit(1);
|
2009-08-21 12:31:34 +04:00
|
|
|
}
|
|
|
|
watchdog = optarg;
|
2009-04-25 16:56:19 +04:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_watchdog_action:
|
|
|
|
if (select_watchdog_action(optarg) == -1) {
|
2015-10-30 18:07:58 +03:00
|
|
|
error_report("unknown -watchdog-action parameter");
|
2009-04-25 16:56:19 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2005-01-15 15:02:56 +03:00
|
|
|
case QEMU_OPTION_parallel:
|
2009-12-08 15:11:42 +03:00
|
|
|
add_device_config(DEV_PARALLEL, optarg);
|
|
|
|
default_parallel = 0;
|
2010-03-07 13:28:40 +03:00
|
|
|
if (strncmp(optarg, "mon:", 4) == 0) {
|
|
|
|
default_monitor = 0;
|
|
|
|
}
|
2005-01-15 15:02:56 +03:00
|
|
|
break;
|
debugcon: support for debugging consoles (e.g. Bochs port 0xe9)
Add generic support for debugging consoles (simple I/O ports which
when written to cause debugging output to be written to a target.)
The current implementation matches Bochs' port 0xe9, allowing the same
debugging code to be used for both Bochs and Qemu.
There is no vm state associated with the debugging port, simply
because it has none -- the entire interface is a single, stateless,
write-only port.
Most of the code was cribbed from the serial port driver.
v2: removed non-ISA variants (they can be introduced when/if someone
wants them, using code from the serial port); added configurable
readback (Bochs returns 0xe9 on a read from this register, mimic that
by default) This retains the apparently somewhat controversial user
friendly option, however.
v3: reimplemented the user friendly option as a synthetic option
("-debugcon foo" basically ends up being a parser-level shorthand for
"-chardev stdio,id=debugcon -device isa-debugcon,chardev=debugcon") --
this dramatically reduced the complexity while keeping the same level
of user friendliness.
v4: spaces, not tabs.
v5: update to match current top of tree. Calling qemu_chr_open()
already during parsing no longer works; defer until we are parsing the
other console-like devices.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-30 00:51:36 +03:00
|
|
|
case QEMU_OPTION_debugcon:
|
|
|
|
add_device_config(DEV_DEBUGCON, optarg);
|
|
|
|
break;
|
2015-01-11 13:56:51 +03:00
|
|
|
case QEMU_OPTION_loadvm:
|
|
|
|
loadvm = optarg;
|
|
|
|
break;
|
2004-10-03 17:29:03 +04:00
|
|
|
case QEMU_OPTION_full_screen:
|
2018-02-02 14:10:14 +03:00
|
|
|
dpy.has_full_screen = true;
|
|
|
|
dpy.full_screen = true;
|
2004-10-03 17:29:03 +04:00
|
|
|
break;
|
2007-06-22 01:08:02 +04:00
|
|
|
case QEMU_OPTION_alt_grab:
|
|
|
|
alt_grab = 1;
|
|
|
|
break;
|
2009-09-18 00:48:04 +04:00
|
|
|
case QEMU_OPTION_ctrl_grab:
|
|
|
|
ctrl_grab = 1;
|
|
|
|
break;
|
2006-12-11 05:08:05 +03:00
|
|
|
case QEMU_OPTION_no_quit:
|
2018-02-02 14:10:14 +03:00
|
|
|
dpy.has_window_close = true;
|
|
|
|
dpy.window_close = false;
|
2006-12-11 05:08:05 +03:00
|
|
|
break;
|
2009-01-16 01:14:11 +03:00
|
|
|
case QEMU_OPTION_sdl:
|
2013-06-15 14:44:20 +04:00
|
|
|
#ifdef CONFIG_SDL
|
2018-02-02 14:10:15 +03:00
|
|
|
dpy.type = DISPLAY_TYPE_SDL;
|
2009-01-16 01:14:11 +03:00
|
|
|
break;
|
2011-03-16 15:33:34 +03:00
|
|
|
#else
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("SDL support is disabled");
|
2011-03-16 15:33:34 +03:00
|
|
|
exit(1);
|
2006-12-11 05:08:05 +03:00
|
|
|
#endif
|
2004-12-09 01:21:25 +03:00
|
|
|
case QEMU_OPTION_pidfile:
|
2007-03-19 18:58:31 +03:00
|
|
|
pid_file = optarg;
|
2004-12-09 01:21:25 +03:00
|
|
|
break;
|
2005-04-30 20:10:35 +04:00
|
|
|
case QEMU_OPTION_win2k_hack:
|
|
|
|
win2k_install_hack = 1;
|
|
|
|
break;
|
2009-02-27 23:12:36 +03:00
|
|
|
case QEMU_OPTION_acpitable:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("acpi"),
|
|
|
|
optarg, true);
|
2013-11-28 21:12:59 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2016-12-22 19:12:33 +03:00
|
|
|
acpi_table_add(opts, &error_fatal);
|
2009-02-27 23:12:36 +03:00
|
|
|
break;
|
qemu: Add support for SMBIOS command line otions (Alex Williamson)
Create a new -smbios option (x86-only) to allow binary SMBIOS entries
to be passed through to the BIOS or modify the default values of
individual fields of type 0 and 1 entries on the command line.
Binary SMBIOS entries can be generated as follows:
dmidecode -t 1 -u | grep $'^\t\t[^"]' | xargs -n1 | \
perl -lne 'printf "%c", hex($_)' > smbios_type_1.bin
These can then be passed to the BIOS using this switch:
-smbios file=smbios_type_1.bin
Command line generation supports the following syntax:
-smbios type=0[,vendor=str][,version=str][,date=str][,release=%d.%d]
-smbios type=1[,manufacturer=str][,product=str][,version=str][,serial=str]
[,uuid=$(uuidgen)][,sku=str][,family=str]
For instance, to add a serial number to the type 1 table:
-smbios type=1,serial=0123456789
Interface is extensible to support more fields/tables as needed.
aliguori: remove texi formatting from help output
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7163 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-17 22:59:56 +04:00
|
|
|
case QEMU_OPTION_smbios:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("smbios"),
|
|
|
|
optarg, false);
|
2013-11-28 21:12:59 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2016-12-22 18:18:28 +03:00
|
|
|
smbios_entry_add(opts, &error_fatal);
|
qemu: Add support for SMBIOS command line otions (Alex Williamson)
Create a new -smbios option (x86-only) to allow binary SMBIOS entries
to be passed through to the BIOS or modify the default values of
individual fields of type 0 and 1 entries on the command line.
Binary SMBIOS entries can be generated as follows:
dmidecode -t 1 -u | grep $'^\t\t[^"]' | xargs -n1 | \
perl -lne 'printf "%c", hex($_)' > smbios_type_1.bin
These can then be passed to the BIOS using this switch:
-smbios file=smbios_type_1.bin
Command line generation supports the following syntax:
-smbios type=0[,vendor=str][,version=str][,date=str][,release=%d.%d]
-smbios type=1[,manufacturer=str][,product=str][,version=str][,serial=str]
[,uuid=$(uuidgen)][,sku=str][,family=str]
For instance, to add a serial number to the type 1 table:
-smbios type=1,serial=0123456789
Interface is extensible to support more fields/tables as needed.
aliguori: remove texi formatting from help output
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7163 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-17 22:59:56 +04:00
|
|
|
break;
|
2015-04-29 18:21:53 +03:00
|
|
|
case QEMU_OPTION_fwcfg:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("fw_cfg"),
|
|
|
|
optarg, true);
|
2015-04-29 18:21:53 +03:00
|
|
|
if (opts == NULL) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2018-05-11 20:24:43 +03:00
|
|
|
case QEMU_OPTION_preconfig:
|
|
|
|
preconfig_exit_requested = false;
|
|
|
|
break;
|
2008-11-05 19:04:33 +03:00
|
|
|
case QEMU_OPTION_enable_kvm:
|
2010-09-21 23:05:31 +04:00
|
|
|
olist = qemu_find_opts("machine");
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
qemu_opts_parse_noisily(olist, "accel=kvm", false);
|
2010-09-21 23:05:31 +04:00
|
|
|
break;
|
2015-01-07 15:11:38 +03:00
|
|
|
case QEMU_OPTION_M:
|
2010-09-21 23:05:31 +04:00
|
|
|
case QEMU_OPTION_machine:
|
|
|
|
olist = qemu_find_opts("machine");
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(olist, optarg, true);
|
2010-09-21 23:05:31 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2008-11-05 19:04:33 +03:00
|
|
|
break;
|
2012-10-05 21:51:45 +04:00
|
|
|
case QEMU_OPTION_no_kvm:
|
|
|
|
olist = qemu_find_opts("machine");
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
qemu_opts_parse_noisily(olist, "accel=tcg", false);
|
2012-10-05 21:51:45 +04:00
|
|
|
break;
|
2017-06-08 08:20:57 +03:00
|
|
|
case QEMU_OPTION_accel:
|
2017-02-23 21:29:08 +03:00
|
|
|
accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"),
|
|
|
|
optarg, true);
|
|
|
|
optarg = qemu_opt_get(accel_opts, "accel");
|
2017-05-04 08:24:41 +03:00
|
|
|
if (!optarg || is_help_option(optarg)) {
|
2019-05-31 00:57:55 +03:00
|
|
|
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]);
|
2020-01-10 12:17:09 +03:00
|
|
|
g_strfreev(optname);
|
2019-05-31 00:57:55 +03:00
|
|
|
}
|
|
|
|
g_free(typename);
|
|
|
|
}
|
|
|
|
g_slist_free(accel_list);
|
2017-06-08 08:20:57 +03:00
|
|
|
exit(0);
|
2017-02-23 21:29:08 +03:00
|
|
|
}
|
2019-09-23 15:00:29 +03:00
|
|
|
if (optarg && strchr(optarg, ':')) {
|
|
|
|
error_report("Don't use ':' with -accel, "
|
|
|
|
"use -M accel=... for now instead");
|
|
|
|
exit(1);
|
|
|
|
}
|
2017-02-23 21:29:08 +03:00
|
|
|
break;
|
2005-11-05 17:22:28 +03:00
|
|
|
case QEMU_OPTION_usb:
|
2012-11-22 20:48:45 +04:00
|
|
|
olist = qemu_find_opts("machine");
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
qemu_opts_parse_noisily(olist, "usb=on", false);
|
2005-11-05 17:22:28 +03:00
|
|
|
break;
|
2005-11-06 19:13:29 +03:00
|
|
|
case QEMU_OPTION_usbdevice:
|
2017-05-19 09:35:16 +03:00
|
|
|
error_report("'-usbdevice' is deprecated, please use "
|
|
|
|
"'-device usb-...' instead");
|
2012-11-22 20:48:45 +04:00
|
|
|
olist = qemu_find_opts("machine");
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
qemu_opts_parse_noisily(olist, "usb=on", false);
|
2009-07-15 15:59:26 +04:00
|
|
|
add_device_config(DEV_USB, optarg);
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_device:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
if (!qemu_opts_parse_noisily(qemu_find_opts("device"),
|
|
|
|
optarg, true)) {
|
2009-07-31 14:25:37 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
2005-11-06 19:13:29 +03:00
|
|
|
break;
|
2005-11-22 02:25:50 +03:00
|
|
|
case QEMU_OPTION_smp:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
if (!qemu_opts_parse_noisily(qemu_find_opts("smp-opts"),
|
|
|
|
optarg, true)) {
|
2009-07-23 19:03:42 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
2005-11-22 02:25:50 +03:00
|
|
|
break;
|
2015-01-11 13:56:51 +03:00
|
|
|
case QEMU_OPTION_vnc:
|
2016-05-12 17:09:59 +03:00
|
|
|
vnc_parse(optarg, &error_fatal);
|
2011-03-16 15:33:36 +03:00
|
|
|
break;
|
2006-05-04 02:02:44 +04:00
|
|
|
case QEMU_OPTION_no_acpi:
|
|
|
|
acpi_enabled = 0;
|
|
|
|
break;
|
2008-12-18 02:28:44 +03:00
|
|
|
case QEMU_OPTION_no_hpet:
|
|
|
|
no_hpet = 1;
|
|
|
|
break;
|
2006-10-02 23:44:22 +04:00
|
|
|
case QEMU_OPTION_no_reboot:
|
|
|
|
no_reboot = 1;
|
|
|
|
break;
|
2008-04-12 01:35:52 +04:00
|
|
|
case QEMU_OPTION_no_shutdown:
|
|
|
|
no_shutdown = 1;
|
|
|
|
break;
|
2007-05-01 05:34:14 +04:00
|
|
|
case QEMU_OPTION_show_cursor:
|
2020-01-31 14:56:03 +03:00
|
|
|
warn_report("The -show-cursor option is deprecated, "
|
|
|
|
"use -display {sdl,gtk},show-cursor=on instead");
|
2020-02-07 12:46:13 +03:00
|
|
|
dpy.has_show_cursor = true;
|
|
|
|
dpy.show_cursor = true;
|
2007-05-01 05:34:14 +04:00
|
|
|
break;
|
2008-09-18 22:29:08 +04:00
|
|
|
case QEMU_OPTION_uuid:
|
2016-09-21 07:27:22 +03:00
|
|
|
if (qemu_uuid_parse(optarg, &qemu_uuid) < 0) {
|
2015-10-30 18:07:56 +03:00
|
|
|
error_report("failed to parse UUID string: wrong format");
|
2008-09-18 22:29:08 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
smbios: Make multiple -smbios type= accumulate sanely
Currently, -smbios type=T,NAME=VAL,... adds one field (T,NAME) with
value VAL to fw_cfg for each unique NAME. If NAME occurs multiple
times, the last one's VAL is used (before the QemuOpts conversion, the
first one was used).
Multiple -smbios can add multiple fields with the same (T, NAME).
SeaBIOS reads all of them from fw_cfg, but uses only the first field
(T, NAME). The others are ignored.
"First one wins, subsequent ones get ignored silently" isn't nice. We
commonly let the last option win. Useful, because it lets you
-readconfig first, then selectively override with command line
options.
Clean up -smbios to work the common way. Accumulate the settings,
with later ones overwriting earlier ones. Put the result into fw_cfg
(no more useless duplicates).
Bonus cleanup: qemu_uuid_parse() no longer sets SMBIOS system uuid by
side effect.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2013-08-16 17:18:31 +04:00
|
|
|
qemu_uuid_set = true;
|
2008-09-18 22:29:08 +04:00
|
|
|
break;
|
2015-01-11 13:56:51 +03:00
|
|
|
case QEMU_OPTION_option_rom:
|
|
|
|
if (nb_option_roms >= MAX_OPTION_ROMS) {
|
2015-10-30 18:07:58 +03:00
|
|
|
error_report("too many option ROMs");
|
2015-01-11 13:56:51 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("option-rom"),
|
|
|
|
optarg, true);
|
2013-02-09 00:22:19 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2010-12-08 14:35:07 +03:00
|
|
|
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) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("Option ROM file is not specified");
|
2010-12-08 14:35:07 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
2015-01-11 13:56:51 +03:00
|
|
|
nb_option_roms++;
|
|
|
|
break;
|
2007-01-20 20:12:09 +03:00
|
|
|
case QEMU_OPTION_semihosting:
|
2019-05-13 16:43:57 +03:00
|
|
|
qemu_semihosting_enable();
|
2014-12-11 15:07:48 +03:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_semihosting_config:
|
2019-05-13 16:43:57 +03:00
|
|
|
if (qemu_semihosting_config_options(optarg) != 0) {
|
2014-12-11 15:07:48 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
2007-01-20 20:12:09 +03:00
|
|
|
break;
|
2007-03-19 18:17:08 +03:00
|
|
|
case QEMU_OPTION_name:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("name"),
|
|
|
|
optarg, true);
|
2014-01-30 14:20:30 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2007-03-19 18:17:08 +03:00
|
|
|
break;
|
2007-05-01 18:16:52 +04:00
|
|
|
case QEMU_OPTION_prom_env:
|
|
|
|
if (nb_prom_envs >= MAX_PROM_ENVS) {
|
2015-10-30 18:07:58 +03:00
|
|
|
error_report("too many prom variables");
|
2007-05-01 18:16:52 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
prom_envs[nb_prom_envs] = optarg;
|
|
|
|
nb_prom_envs++;
|
|
|
|
break;
|
2007-07-28 02:08:46 +04:00
|
|
|
case QEMU_OPTION_old_param:
|
|
|
|
old_param = 1;
|
2008-01-08 22:32:16 +03:00
|
|
|
break;
|
2009-09-15 15:36:04 +04:00
|
|
|
case QEMU_OPTION_rtc:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("rtc"), optarg,
|
|
|
|
false);
|
2009-09-15 15:36:04 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
2007-11-07 19:24:33 +03:00
|
|
|
}
|
|
|
|
break;
|
2008-05-28 16:30:31 +04:00
|
|
|
case QEMU_OPTION_tb_size:
|
2017-07-09 10:49:53 +03:00
|
|
|
#ifndef CONFIG_TCG
|
|
|
|
error_report("TCG is disabled");
|
|
|
|
exit(1);
|
|
|
|
#endif
|
2019-11-13 17:16:44 +03:00
|
|
|
warn_report("The -tb-size option is deprecated, use -accel tcg,tb-size instead");
|
|
|
|
object_register_sugar_prop(ACCEL_CLASS_NAME("tcg"), "tb-size", optarg);
|
2008-05-28 16:30:31 +04:00
|
|
|
break;
|
2008-06-29 05:03:05 +04:00
|
|
|
case QEMU_OPTION_icount:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
icount_opts = qemu_opts_parse_noisily(qemu_find_opts("icount"),
|
|
|
|
optarg, true);
|
2014-07-25 13:56:28 +04:00
|
|
|
if (!icount_opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2008-06-29 05:03:05 +04:00
|
|
|
break;
|
2008-10-13 07:12:02 +04:00
|
|
|
case QEMU_OPTION_incoming:
|
2015-02-26 17:16:06 +03:00
|
|
|
if (!incoming) {
|
|
|
|
runstate_set(RUN_STATE_INMIGRATE);
|
|
|
|
}
|
2008-10-13 07:12:02 +04:00
|
|
|
incoming = optarg;
|
|
|
|
break;
|
2017-01-16 14:31:51 +03:00
|
|
|
case QEMU_OPTION_only_migratable:
|
Revert "migration: move only_migratable to MigrationState"
This reverts commit 3df663e575f1876d7f3bc684f80e72fca0703d39.
This reverts commit b605c47b57b58e61a901a50a0762dccf43d94783.
Command line option --only-migratable is for disallowing any
configuration that can block migration.
Initially, --only-migratable set global variable @only_migratable.
Commit 3df663e575 "migration: move only_migratable to MigrationState"
replaced it by MigrationState member @only_migratable. That was a
mistake.
First, it doesn't make sense on the design level. MigrationState
captures the state of an individual migration, but --only-migratable
isn't a property of an individual migration, it's a restriction on
QEMU configuration. With fault tolerance, we could have several
migrations at once. --only-migratable would certainly protect all of
them. Storing it in MigrationState feels inappropriate.
Second, it contributes to a dependency cycle that manifests itself as
a bug now.
Putting @only_migratable into MigrationState means its available only
after migration_object_init().
We can't set it before migration_object_init(), so we delay setting it
with a global property (this is fixup commit b605c47b57 "migration:
fix handling for --only-migratable").
We can't get it before migration_object_init(), so anything that uses
it can only run afterwards.
Since migrate_add_blocker() needs to obey --only-migratable, any code
adding migration blockers can run only afterwards. This contributes
to the following dependency cycle:
* configure_blockdev() must run before machine_set_property()
so machine properties can refer to block backends
* machine_set_property() before configure_accelerator()
so machine properties like kvm-irqchip get applied
* configure_accelerator() before migration_object_init()
so that Xen's accelerator compat properties get applied.
* migration_object_init() before configure_blockdev()
so configure_blockdev() can add migration blockers
The cycle was closed when recent commit cda4aa9a5a0 "Create block
backends before setting machine properties" added the first
dependency, and satisfied it by violating the last one. Broke block
backends that add migration blockers.
Moving @only_migratable into MigrationState was a mistake. Revert it.
This doesn't quite break the "migration_object_init() before
configure_blockdev() dependency, since migrate_add_blocker() still has
another dependency on migration_object_init(). To be addressed the
next commit.
Note that the reverted commit made -only-migratable sugar for -global
migration.only-migratable=on below the hood. Documentation has only
ever mentioned -only-migratable. This commit removes the arcane &
undocumented alternative to -only-migratable again. Nobody should be
using it.
Conflicts:
include/migration/misc.h
migration/migration.c
migration/migration.h
vl.c
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20190401090827.20793-3-armbru@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
2019-04-01 12:08:24 +03:00
|
|
|
only_migratable = 1;
|
2017-01-16 14:31:51 +03:00
|
|
|
break;
|
2009-12-08 15:11:46 +03:00
|
|
|
case QEMU_OPTION_nodefaults:
|
2014-03-10 18:37:40 +04:00
|
|
|
has_defaults = 0;
|
2009-12-08 15:11:46 +03:00
|
|
|
break;
|
2009-04-22 19:19:10 +04:00
|
|
|
case QEMU_OPTION_xen_domid:
|
2010-03-29 23:23:52 +04:00
|
|
|
if (!(xen_available())) {
|
2016-05-31 11:31:38 +03:00
|
|
|
error_report("Option not supported for this target");
|
2010-03-29 23:23:52 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
2009-04-22 19:19:10 +04:00
|
|
|
xen_domid = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_xen_attach:
|
2010-03-29 23:23:52 +04:00
|
|
|
if (!(xen_available())) {
|
2016-05-31 11:31:38 +03:00
|
|
|
error_report("Option not supported for this target");
|
2010-03-29 23:23:52 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
2009-04-22 19:19:10 +04:00
|
|
|
xen_mode = XEN_ATTACH;
|
|
|
|
break;
|
2017-03-22 12:39:15 +03:00
|
|
|
case QEMU_OPTION_xen_domid_restrict:
|
|
|
|
if (!(xen_available())) {
|
|
|
|
error_report("Option not supported for this target");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
xen_domid_restrict = true;
|
|
|
|
break;
|
2010-08-09 14:48:32 +04:00
|
|
|
case QEMU_OPTION_trace:
|
2016-06-17 17:44:10 +03:00
|
|
|
g_free(trace_file);
|
|
|
|
trace_file = trace_opt_parse(optarg);
|
2010-08-09 14:48:32 +04:00
|
|
|
break;
|
2017-07-24 17:28:22 +03:00
|
|
|
case QEMU_OPTION_plugin:
|
|
|
|
qemu_plugin_opt_parse(optarg, &plugin_list);
|
|
|
|
break;
|
2009-10-14 12:39:28 +04:00
|
|
|
case QEMU_OPTION_readconfig:
|
|
|
|
{
|
2010-03-05 19:25:55 +03:00
|
|
|
int ret = qemu_read_config_file(optarg);
|
|
|
|
if (ret < 0) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("read config %s: %s", optarg,
|
|
|
|
strerror(-ret));
|
2009-10-14 12:39:28 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2010-03-11 17:13:27 +03:00
|
|
|
case QEMU_OPTION_spice:
|
|
|
|
olist = qemu_find_opts("spice");
|
|
|
|
if (!olist) {
|
2015-10-30 18:08:02 +03:00
|
|
|
error_report("spice support is disabled");
|
2010-03-11 17:13:27 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(olist, optarg, false);
|
2010-03-11 17:13:27 +03:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-02-25 19:02:30 +04:00
|
|
|
display_remote++;
|
2010-03-11 17:13:27 +03:00
|
|
|
break;
|
2009-10-14 12:39:28 +04:00
|
|
|
case QEMU_OPTION_writeconfig:
|
|
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
if (strcmp(optarg, "-") == 0) {
|
|
|
|
fp = stdout;
|
|
|
|
} else {
|
|
|
|
fp = fopen(optarg, "w");
|
|
|
|
if (fp == NULL) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("open %s: %s", optarg,
|
|
|
|
strerror(errno));
|
2009-10-14 12:39:28 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
qemu_config_write(fp);
|
2014-04-22 05:12:34 +04:00
|
|
|
if (fp != stdout) {
|
|
|
|
fclose(fp);
|
|
|
|
}
|
2009-10-14 12:39:28 +04:00
|
|
|
break;
|
|
|
|
}
|
2012-03-28 17:42:02 +04:00
|
|
|
case QEMU_OPTION_qtest:
|
|
|
|
qtest_chrdev = optarg;
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_qtest_log:
|
|
|
|
qtest_log = optarg;
|
|
|
|
break;
|
2012-08-15 01:44:08 +04:00
|
|
|
case QEMU_OPTION_sandbox:
|
2019-04-29 16:47:57 +03:00
|
|
|
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);
|
2012-08-15 01:44:08 +04:00
|
|
|
if (!opts) {
|
2013-02-09 00:22:19 +04:00
|
|
|
exit(1);
|
2012-08-15 01:44:08 +04:00
|
|
|
}
|
|
|
|
break;
|
2012-10-18 23:19:34 +04:00
|
|
|
case QEMU_OPTION_add_fd:
|
|
|
|
#ifndef _WIN32
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("add-fd"),
|
|
|
|
optarg, false);
|
2012-10-18 23:19:34 +04:00
|
|
|
if (!opts) {
|
2013-02-09 00:22:19 +04:00
|
|
|
exit(1);
|
2012-10-18 23:19:34 +04:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
error_report("File descriptor passing is disabled on this "
|
|
|
|
"platform");
|
|
|
|
exit(1);
|
|
|
|
#endif
|
|
|
|
break;
|
2012-06-25 23:36:33 +04:00
|
|
|
case QEMU_OPTION_object:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
|
|
|
|
optarg, true);
|
2013-02-09 00:22:19 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2012-06-25 23:36:33 +04:00
|
|
|
break;
|
2013-04-19 18:42:06 +04:00
|
|
|
case QEMU_OPTION_realtime:
|
2019-04-11 20:53:45 +03:00
|
|
|
warn_report("'-realtime mlock=...' is deprecated, please use "
|
|
|
|
"'-overcommit mem-lock=...' instead");
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("realtime"),
|
|
|
|
optarg, false);
|
2013-04-19 18:42:06 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2018-06-22 22:22:05 +03:00
|
|
|
/* Don't override the -overcommit option if set */
|
|
|
|
enable_mlock = enable_mlock ||
|
|
|
|
qemu_opt_get_bool(opts, "mlock", true);
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_overcommit:
|
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("overcommit"),
|
|
|
|
optarg, false);
|
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
/* Don't override the -realtime option if set */
|
|
|
|
enable_mlock = enable_mlock ||
|
|
|
|
qemu_opt_get_bool(opts, "mem-lock", false);
|
|
|
|
enable_cpu_pm = qemu_opt_get_bool(opts, "cpu-pm", false);
|
2013-04-19 18:42:06 +04:00
|
|
|
break;
|
2013-07-04 07:02:46 +04:00
|
|
|
case QEMU_OPTION_msg:
|
QemuOpts: Wean off qerror_report_err()
qerror_report_err() is a transitional interface to help with
converting existing monitor commands to QMP. It should not be used
elsewhere.
The only remaining user in qemu-option.c is qemu_opts_parse(). Is it
used in QMP context? If not, we can simply replace
qerror_report_err() by error_report_err().
The uses in qemu-img.c, qemu-io.c, qemu-nbd.c and under tests/ are
clearly not in QMP context.
The uses in vl.c aren't either, because the only QMP command handlers
there are qmp_query_status() and qmp_query_machines(), and they don't
call it.
Remaining uses:
* drive_def(): Command line -drive and such, HMP drive_add and pci_add
* hmp_chardev_add(): HMP chardev-add
* monitor_parse_command(): HMP core
* tmp_config_parse(): Command line -tpmdev
* net_host_device_add(): HMP host_net_add
* net_client_parse(): Command line -net and -netdev
* qemu_global_option(): Command line -global
* vnc_parse_func(): Command line -display, -vnc, default display, HMP
change, QMP change. Bummer.
* qemu_pci_hot_add_nic(): HMP pci_add
* usb_net_init(): Command line -usbdevice, HMP usb_add
Propagate errors through qemu_opts_parse(). Create a convenience
function qemu_opts_parse_noisily() that passes errors to
error_report_err(). Switch all non-QMP users outside tests to it.
That leaves vnc_parse_func(). Propagate errors through it. Since I'm
touching it anyway, rename it to vnc_parse().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
2015-02-13 14:50:26 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("msg"), optarg,
|
|
|
|
false);
|
2013-07-04 07:02:46 +04:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
configure_msg(opts);
|
|
|
|
break;
|
2014-06-20 17:26:08 +04:00
|
|
|
case QEMU_OPTION_dump_vmstate:
|
2014-10-29 15:49:43 +03:00
|
|
|
if (vmstate_dump_file) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("only one '-dump-vmstate' "
|
|
|
|
"option may be given");
|
2014-10-29 15:49:43 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
2014-06-20 17:26:08 +04:00
|
|
|
vmstate_dump_file = fopen(optarg, "w");
|
|
|
|
if (vmstate_dump_file == NULL) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("open %s: %s", optarg, strerror(errno));
|
2014-06-20 17:26:08 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
2018-08-15 18:42:49 +03:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_enable_sync_profile:
|
|
|
|
qsp_enable();
|
2014-06-20 17:26:08 +04:00
|
|
|
break;
|
2018-05-14 16:45:45 +03:00
|
|
|
case QEMU_OPTION_nouserconfig:
|
|
|
|
/* Nothing to be parsed here. Especially, do not error out below. */
|
|
|
|
break;
|
2010-06-10 13:42:25 +04:00
|
|
|
default:
|
2018-05-04 20:01:07 +03:00
|
|
|
if (os_parse_cmd_args(popt->index, optarg)) {
|
|
|
|
error_report("Option not supported in this build");
|
|
|
|
exit(1);
|
|
|
|
}
|
2004-05-14 02:02:20 +04:00
|
|
|
}
|
2003-06-24 17:42:40 +04:00
|
|
|
}
|
|
|
|
}
|
2016-02-12 22:02:25 +03:00
|
|
|
/*
|
|
|
|
* Clear error location left behind by the loop.
|
|
|
|
* Best done right after the loop. Do not insert code here!
|
|
|
|
*/
|
|
|
|
loc_set_none();
|
2015-01-07 15:11:38 +03:00
|
|
|
|
2019-03-08 16:14:36 +03:00
|
|
|
user_register_global_props();
|
|
|
|
|
2015-09-17 19:25:18 +03:00
|
|
|
replay_configure(icount_opts);
|
|
|
|
|
2018-05-11 20:24:43 +03:00
|
|
|
if (incoming && !preconfig_exit_requested) {
|
|
|
|
error_report("'preconfig' and 'incoming' options are "
|
|
|
|
"mutually exclusive");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2018-10-18 10:12:54 +03:00
|
|
|
configure_rtc(qemu_find_opts_singleton("rtc"));
|
|
|
|
|
2016-02-16 17:51:53 +03:00
|
|
|
machine_class = select_machine();
|
qdev: Fix latent bug with compat_props and onboard devices
Compatibility properties started life as a qdev property thing: we
supported them only for qdev properties, and implemented them with the
machinery backing command line option -global.
Recent commit fa0cb34d221 put them to use (tacitly) with memory
backend objects (subtypes of TYPE_MEMORY_BACKEND). To make that
possible, we first moved the work of applying them from the -global
machinery into TYPE_DEVICE's .instance_post_init() method
device_post_init(), in commits ea9ce8934c5 and b66bbee39f6, then made
it available to TYPE_MEMORY_BACKEND's .instance_post_init() method
host_memory_backend_post_init() as object_apply_compat_props(), in
commit 1c3994f6d2a.
Note the code smell: we now have function name starting with object_
in hw/core/qdev.c. It has to be there rather than in qom/, because it
calls qdev_get_machine() to find the current accelerator's and
machine's compat_props.
Turns out calling qdev_get_machine() there is problematic. If we
qdev_create() from a machine's .instance_init() method, we call
device_post_init() and thus qdev_get_machine() before main() can
create "/machine" in QOM. qdev_get_machine() tries to get it with
container_get(), which "helpfully" creates it as "container" object,
and returns that. object_apply_compat_props() tries to paper over the
problem by doing nothing when the value of qdev_get_machine() isn't a
TYPE_MACHINE. But the damage is done already: when main() later
attempts to create the real "/machine", it fails with "attempt to add
duplicate property 'machine' to object (type 'container')", and
aborts.
Since no machine .instance_init() calls qdev_create() so far, the bug
is latent. But since I want to do that, I get to fix the bug first.
Observe that object_apply_compat_props() doesn't actually need the
MachineState, only its the compat_props member of its MachineClass and
AccelClass. This permits a simple fix: register MachineClass and
AccelClass compat_props with the object_apply_compat_props() machinery
right after these classes get selected.
This is actually similar to how things worked before commits
ea9ce8934c5 and b66bbee39f6, except we now register much earlier. The
old code registered them only after the machine's .instance_init()
ran, which would've broken compatibility properties for any devices
created there.
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20190308131445.17502-2-armbru@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
2019-03-08 16:14:34 +03:00
|
|
|
object_set_machine_compat_props(machine_class->compat_props);
|
2015-05-07 08:33:57 +03:00
|
|
|
|
|
|
|
set_memory_options(&ram_slots, &maxram_size, machine_class);
|
2015-01-11 13:38:43 +03:00
|
|
|
|
2014-06-02 17:25:00 +04:00
|
|
|
os_daemonize();
|
2020-02-20 07:11:10 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If QTest is enabled, keep the rcu_atfork enabled, since system processes
|
|
|
|
* may be forked testing purposes (e.g. fork-server based fuzzing) The fork
|
|
|
|
* should happen before a signle cpu instruction is executed, to prevent
|
|
|
|
* deadlocks. See commit 73c6e40, rcu: "completely disable pthread_atfork
|
|
|
|
* callbacks as soon as possible"
|
|
|
|
*/
|
|
|
|
if (!qtest_enabled()) {
|
|
|
|
rcu_disable_atfork();
|
|
|
|
}
|
2014-06-02 17:25:00 +04:00
|
|
|
|
util: add qemu_write_pidfile()
There are variants of qemu_create_pidfile() in qemu-pr-helper and
qemu-ga. Let's have a common implementation in libqemuutil.
The code is initially based from pr-helper write_pidfile(), with
various improvements and suggestions from Daniel Berrangé:
QEMU will leave the pidfile existing on disk when it exits which
initially made me think it avoids the deletion race. The app
managing QEMU, however, may well delete the pidfile after it has
seen QEMU exit, and even if the app locks the pidfile before
deleting it, there is still a race.
eg consider the following sequence
QEMU 1 libvirtd QEMU 2
1. lock(pidfile)
2. exit()
3. open(pidfile)
4. lock(pidfile)
5. open(pidfile)
6. unlink(pidfile)
7. close(pidfile)
8. lock(pidfile)
IOW, at step 8 the new QEMU has successfully acquired the lock, but
the pidfile no longer exists on disk because it was deleted after
the original QEMU exited.
While we could just say no external app should ever delete the
pidfile, I don't think that is satisfactory as people don't read
docs, and admins don't like stale pidfiles being left around on
disk.
To make this robust, I think we might want to copy libvirt's
approach to pidfile acquisition which runs in a loop and checks that
the file on disk /after/ acquiring the lock matches the file that
was locked. Then we could in fact safely let QEMU delete its own
pidfiles on clean exit..
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20180831145314.14736-2-marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-08-31 17:53:12 +03:00
|
|
|
if (pid_file && !qemu_write_pidfile(pid_file, &err)) {
|
|
|
|
error_reportf_err(err, "cannot create PID file: ");
|
2016-11-02 17:18:50 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2018-09-07 15:13:19 +03:00
|
|
|
qemu_unlink_pidfile_notifier.notify = qemu_unlink_pidfile;
|
|
|
|
qemu_add_exit_notifier(&qemu_unlink_pidfile_notifier);
|
|
|
|
|
2014-09-18 15:30:49 +04:00
|
|
|
if (qemu_init_main_loop(&main_loop_err)) {
|
2015-02-12 15:55:05 +03:00
|
|
|
error_report_err(main_loop_err);
|
2012-10-30 03:17:12 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2018-05-31 06:29:37 +03:00
|
|
|
#ifdef CONFIG_SECCOMP
|
2018-08-30 17:33:48 +03:00
|
|
|
olist = qemu_find_opts_err("sandbox", NULL);
|
2018-10-17 11:26:41 +03:00
|
|
|
if (olist) {
|
|
|
|
qemu_opts_foreach(olist, parse_sandbox, NULL, &error_fatal);
|
2012-08-15 01:44:08 +04:00
|
|
|
}
|
2018-05-31 06:29:37 +03:00
|
|
|
#endif
|
2012-08-15 01:44:08 +04:00
|
|
|
|
2018-10-17 11:26:59 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("name"),
|
|
|
|
parse_name, NULL, &error_fatal);
|
2014-05-06 15:15:55 +04:00
|
|
|
|
2012-10-18 23:19:34 +04:00
|
|
|
#ifndef _WIN32
|
2018-10-17 11:26:42 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("add-fd"),
|
|
|
|
parse_add_fd, NULL, &error_fatal);
|
2012-10-18 23:19:34 +04:00
|
|
|
|
2018-10-17 11:26:42 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("add-fd"),
|
|
|
|
cleanup_add_fd, NULL, &error_fatal);
|
2012-10-18 23:19:34 +04:00
|
|
|
#endif
|
|
|
|
|
2019-11-13 15:57:55 +03:00
|
|
|
current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class)));
|
2014-12-16 19:58:06 +03:00
|
|
|
if (machine_help_func(qemu_get_machine_opts(), current_machine)) {
|
|
|
|
exit(0);
|
|
|
|
}
|
2014-03-05 21:30:47 +04:00
|
|
|
object_property_add_child(object_get_root(), "machine",
|
|
|
|
OBJECT(current_machine), &error_abort);
|
2019-03-08 16:14:37 +03:00
|
|
|
object_property_add_child(container_get(OBJECT(current_machine),
|
|
|
|
"/unattached"),
|
|
|
|
"sysbus", OBJECT(sysbus_get_default()),
|
|
|
|
NULL);
|
2016-10-24 18:26:49 +03:00
|
|
|
|
|
|
|
if (machine_class->minimum_page_bits) {
|
|
|
|
if (!set_preferred_target_page_bits(machine_class->minimum_page_bits)) {
|
|
|
|
/* This would be a board error: specifying a minimum smaller than
|
|
|
|
* a target's compile-time fixed setting.
|
|
|
|
*/
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-11 12:52:32 +04:00
|
|
|
cpu_exec_init_all();
|
2014-03-05 21:30:47 +04:00
|
|
|
|
2014-04-09 21:34:53 +04:00
|
|
|
if (machine_class->hw_version) {
|
2015-10-30 22:36:08 +03:00
|
|
|
qemu_set_hw_version(machine_class->hw_version);
|
2012-05-30 07:35:51 +04:00
|
|
|
}
|
|
|
|
|
2019-04-17 05:59:40 +03:00
|
|
|
if (cpu_option && is_help_option(cpu_option)) {
|
|
|
|
list_cpus(cpu_option);
|
2012-03-09 23:19:07 +04:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2016-02-09 19:49:05 +03:00
|
|
|
if (!trace_init_backends()) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2016-01-07 16:55:24 +03:00
|
|
|
trace_init_file(trace_file);
|
|
|
|
|
2015-06-10 17:20:24 +03:00
|
|
|
/* Open the logfile at this point and set the log mask if necessary.
|
2011-06-07 20:32:40 +04:00
|
|
|
*/
|
2020-01-23 22:36:26 +03:00
|
|
|
qemu_set_log_filename(log_file, &error_fatal);
|
2011-06-07 20:32:40 +04:00
|
|
|
if (log_mask) {
|
2013-02-11 20:41:24 +04:00
|
|
|
int mask;
|
|
|
|
mask = qemu_str_to_log_mask(log_mask);
|
|
|
|
if (!mask) {
|
|
|
|
qemu_print_log_usage(stdout);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
qemu_set_log(mask);
|
2016-01-07 16:55:30 +03:00
|
|
|
} else {
|
|
|
|
qemu_set_log(0);
|
2011-06-07 20:32:40 +04:00
|
|
|
}
|
2003-07-26 22:11:40 +04:00
|
|
|
|
2017-09-14 14:42:36 +03:00
|
|
|
/* add configured firmware directories */
|
|
|
|
dirs = g_strsplit(CONFIG_QEMU_FIRMWAREPATH, G_SEARCHPATH_SEPARATOR_S, 0);
|
|
|
|
for (i = 0; dirs[i] != NULL; i++) {
|
|
|
|
qemu_add_data_dir(dirs[i]);
|
|
|
|
}
|
2018-01-04 19:05:14 +03:00
|
|
|
g_strfreev(dirs);
|
2017-09-14 14:42:36 +03:00
|
|
|
|
|
|
|
/* try to find datadir relative to the executable path */
|
2018-01-04 19:05:14 +03:00
|
|
|
dir = os_find_datadir();
|
|
|
|
qemu_add_data_dir(dir);
|
|
|
|
g_free(dir);
|
2017-09-14 14:42:35 +03:00
|
|
|
|
2017-09-14 14:42:36 +03:00
|
|
|
/* add the datadir specified when building */
|
2017-09-14 14:42:35 +03:00
|
|
|
qemu_add_data_dir(CONFIG_QEMU_DATADIR);
|
2009-05-30 03:52:44 +04:00
|
|
|
|
2016-05-16 19:34:35 +03:00
|
|
|
/* -L help lists the data directories and exits. */
|
|
|
|
if (list_data_dirs) {
|
|
|
|
for (i = 0; i < data_dir_idx; i++) {
|
|
|
|
printf("%s\n", data_dir[i]);
|
|
|
|
}
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2017-11-13 16:55:27 +03:00
|
|
|
/* machine_class: default to UP */
|
|
|
|
machine_class->max_cpus = machine_class->max_cpus ?: 1;
|
|
|
|
machine_class->min_cpus = machine_class->min_cpus ?: 1;
|
|
|
|
machine_class->default_cpus = machine_class->default_cpus ?: 1;
|
|
|
|
|
|
|
|
/* default to machine_class->default_cpus */
|
2019-05-18 23:54:28 +03:00
|
|
|
current_machine->smp.cpus = machine_class->default_cpus;
|
|
|
|
current_machine->smp.max_cpus = machine_class->default_cpus;
|
|
|
|
current_machine->smp.cores = 1;
|
|
|
|
current_machine->smp.threads = 1;
|
2017-11-13 16:55:27 +03:00
|
|
|
|
2019-06-20 08:45:24 +03:00
|
|
|
machine_class->smp_parse(current_machine,
|
|
|
|
qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
|
2009-07-23 19:03:42 +04:00
|
|
|
|
2017-11-13 16:55:27 +03:00
|
|
|
/* sanity-check smp_cpus and max_cpus against machine_class */
|
2019-05-18 23:54:28 +03:00
|
|
|
if (current_machine->smp.cpus < machine_class->min_cpus) {
|
2017-11-13 16:55:27 +03:00
|
|
|
error_report("Invalid SMP CPUs %d. The min CPUs "
|
2019-05-18 23:54:28 +03:00
|
|
|
"supported by machine '%s' is %d",
|
|
|
|
current_machine->smp.cpus,
|
2017-11-13 16:55:27 +03:00
|
|
|
machine_class->name, machine_class->min_cpus);
|
|
|
|
exit(1);
|
|
|
|
}
|
2019-05-18 23:54:28 +03:00
|
|
|
if (current_machine->smp.max_cpus > machine_class->max_cpus) {
|
vl: exit if maxcpus is negative
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---Steps to Reproduce---
When passed a negative number to 'maxcpus' parameter, Qemu aborts
with a core dump.
Run the following command with maxcpus argument as negative number
ppc64-softmmu/qemu-system-ppc64 --nographic -vga none -machine
pseries,accel=kvm,kvm-type=HV -m size=200g -device virtio-blk-pci,
drive=rootdisk -drive file=/home/images/pegas-1.0-ppc64le.qcow2,
if=none,cache=none,id=rootdisk,format=qcow2 -monitor telnet
:127.0.0.1:1234,server,nowait -net nic,model=virtio -net
user -redir tcp:2000::22 -device nec-usb-xhci -smp 8,cores=1,
threads=1,maxcpus=-12
(process:12149): GLib-ERROR **: gmem.c:130: failed to allocate
18446744073709550568 bytes
Trace/breakpoint trap
Reported-by: R.Nageswara Sastry <rnsastry@linux.vnet.ibm.com>
Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
Message-Id: <1504511031-26834-1-git-send-email-s1seetee@linux.vnet.ibm.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2017-09-04 10:43:51 +03:00
|
|
|
error_report("Invalid SMP CPUs %d. The max CPUs "
|
2019-05-18 23:54:28 +03:00
|
|
|
"supported by machine '%s' is %d",
|
|
|
|
current_machine->smp.max_cpus,
|
2015-10-30 18:07:52 +03:00
|
|
|
machine_class->name, machine_class->max_cpus);
|
2008-10-08 00:39:39 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2010-11-22 18:44:15 +03:00
|
|
|
/*
|
|
|
|
* Get the default machine options from the machine if it is not already
|
|
|
|
* specified either by the configuration file or by the command line.
|
|
|
|
*/
|
2014-04-09 21:34:53 +04:00
|
|
|
if (machine_class->default_machine_opts) {
|
2012-01-27 22:55:43 +04:00
|
|
|
qemu_opts_set_defaults(qemu_find_opts("machine"),
|
2014-04-09 21:34:53 +04:00
|
|
|
machine_class->default_machine_opts, 0);
|
2010-11-22 18:44:15 +03:00
|
|
|
}
|
|
|
|
|
2017-07-24 17:28:22 +03:00
|
|
|
/* process plugin before CPUs are created, but once -smp has been parsed */
|
|
|
|
if (qemu_plugin_load_list(&plugin_list)) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2015-03-13 15:35:14 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("device"),
|
|
|
|
default_driver_check, NULL, NULL);
|
|
|
|
qemu_opts_foreach(qemu_find_opts("global"),
|
|
|
|
default_driver_check, NULL, NULL);
|
2009-12-08 15:11:41 +03:00
|
|
|
|
2014-03-10 18:37:40 +04:00
|
|
|
if (!vga_model && !default_vga) {
|
|
|
|
vga_interface_type = VGA_DEVICE;
|
|
|
|
}
|
2014-04-09 21:34:53 +04:00
|
|
|
if (!has_defaults || machine_class->no_serial) {
|
2009-12-08 15:11:54 +03:00
|
|
|
default_serial = 0;
|
|
|
|
}
|
2014-04-09 21:34:53 +04:00
|
|
|
if (!has_defaults || machine_class->no_parallel) {
|
2009-12-08 15:11:54 +03:00
|
|
|
default_parallel = 0;
|
|
|
|
}
|
2014-04-09 21:34:53 +04:00
|
|
|
if (!has_defaults || machine_class->no_floppy) {
|
2009-12-16 16:25:39 +03:00
|
|
|
default_floppy = 0;
|
|
|
|
}
|
2014-04-09 21:34:53 +04:00
|
|
|
if (!has_defaults || machine_class->no_cdrom) {
|
2009-12-16 16:25:39 +03:00
|
|
|
default_cdrom = 0;
|
|
|
|
}
|
2014-04-09 21:34:53 +04:00
|
|
|
if (!has_defaults || machine_class->no_sdcard) {
|
2009-12-16 16:25:39 +03:00
|
|
|
default_sdcard = 0;
|
|
|
|
}
|
2014-03-10 18:37:40 +04:00
|
|
|
if (!has_defaults) {
|
|
|
|
default_monitor = 0;
|
|
|
|
default_net = 0;
|
|
|
|
default_vga = 0;
|
|
|
|
}
|
2009-12-08 15:11:54 +03:00
|
|
|
|
disallow -daemonize usage of stdio (curses display, -nographic, -serial stdio etc)
Curses display requires stdin/out to stay on the terminal,
so -daemonize makes no sense in this case. Instead of
leaving display uninitialized like is done since 995ee2bf469de6bb,
explicitly detect this case earlier and error out.
-nographic can actually be used with -daemonize, by redirecting
everything to a null device, but the problem is that according
to documentation and historical behavour, -nographic redirects
guest ports to stdin/out, which, again, makes no sense in case
of -daemonize. Since -nographic is a legacy option, don't bother
fixing this case (to allow -nographic and -daemonize by redirecting
guest ports to null instead of stdin/out in this case), but disallow
it completely instead, to stop garbling host terminal.
If no display display needed and user wants to use -nographic,
the right way to go is to use
-serial null -parallel null -monitor none -display none -vga none
instead of -nographic.
Also prevent the same issue -- it was possible to get garbled
host tty after
-nographic -daemonize
and it is still possible to have it by using
-serial stdio -daemonize
Fix this by disallowing opening stdio chardev when -daemonize
is specified.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-12-30 12:48:14 +04:00
|
|
|
if (is_daemonized()) {
|
2018-06-20 16:24:19 +03:00
|
|
|
if (!preconfig_exit_requested) {
|
|
|
|
error_report("'preconfig' and 'daemonize' options are "
|
|
|
|
"mutually exclusive");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
disallow -daemonize usage of stdio (curses display, -nographic, -serial stdio etc)
Curses display requires stdin/out to stay on the terminal,
so -daemonize makes no sense in this case. Instead of
leaving display uninitialized like is done since 995ee2bf469de6bb,
explicitly detect this case earlier and error out.
-nographic can actually be used with -daemonize, by redirecting
everything to a null device, but the problem is that according
to documentation and historical behavour, -nographic redirects
guest ports to stdin/out, which, again, makes no sense in case
of -daemonize. Since -nographic is a legacy option, don't bother
fixing this case (to allow -nographic and -daemonize by redirecting
guest ports to null instead of stdin/out in this case), but disallow
it completely instead, to stop garbling host terminal.
If no display display needed and user wants to use -nographic,
the right way to go is to use
-serial null -parallel null -monitor none -display none -vga none
instead of -nographic.
Also prevent the same issue -- it was possible to get garbled
host tty after
-nographic -daemonize
and it is still possible to have it by using
-serial stdio -daemonize
Fix this by disallowing opening stdio chardev when -daemonize
is specified.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-12-30 12:48:14 +04:00
|
|
|
/* 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.
|
|
|
|
*/
|
2016-04-19 22:55:25 +03:00
|
|
|
if (nographic
|
2019-02-02 13:45:32 +03:00
|
|
|
&& (default_parallel || default_serial || default_monitor)) {
|
2015-10-30 18:07:56 +03:00
|
|
|
error_report("-nographic cannot be used with -daemonize");
|
disallow -daemonize usage of stdio (curses display, -nographic, -serial stdio etc)
Curses display requires stdin/out to stay on the terminal,
so -daemonize makes no sense in this case. Instead of
leaving display uninitialized like is done since 995ee2bf469de6bb,
explicitly detect this case earlier and error out.
-nographic can actually be used with -daemonize, by redirecting
everything to a null device, but the problem is that according
to documentation and historical behavour, -nographic redirects
guest ports to stdin/out, which, again, makes no sense in case
of -daemonize. Since -nographic is a legacy option, don't bother
fixing this case (to allow -nographic and -daemonize by redirecting
guest ports to null instead of stdin/out in this case), but disallow
it completely instead, to stop garbling host terminal.
If no display display needed and user wants to use -nographic,
the right way to go is to use
-serial null -parallel null -monitor none -display none -vga none
instead of -nographic.
Also prevent the same issue -- it was possible to get garbled
host tty after
-nographic -daemonize
and it is still possible to have it by using
-serial stdio -daemonize
Fix this by disallowing opening stdio chardev when -daemonize
is specified.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-12-30 12:48:14 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
#ifdef CONFIG_CURSES
|
2018-02-02 14:10:22 +03:00
|
|
|
if (dpy.type == DISPLAY_TYPE_CURSES) {
|
2015-10-30 18:07:56 +03:00
|
|
|
error_report("curses display cannot be used with -daemonize");
|
disallow -daemonize usage of stdio (curses display, -nographic, -serial stdio etc)
Curses display requires stdin/out to stay on the terminal,
so -daemonize makes no sense in this case. Instead of
leaving display uninitialized like is done since 995ee2bf469de6bb,
explicitly detect this case earlier and error out.
-nographic can actually be used with -daemonize, by redirecting
everything to a null device, but the problem is that according
to documentation and historical behavour, -nographic redirects
guest ports to stdin/out, which, again, makes no sense in case
of -daemonize. Since -nographic is a legacy option, don't bother
fixing this case (to allow -nographic and -daemonize by redirecting
guest ports to null instead of stdin/out in this case), but disallow
it completely instead, to stop garbling host terminal.
If no display display needed and user wants to use -nographic,
the right way to go is to use
-serial null -parallel null -monitor none -display none -vga none
instead of -nographic.
Also prevent the same issue -- it was possible to get garbled
host tty after
-nographic -daemonize
and it is still possible to have it by using
-serial stdio -daemonize
Fix this by disallowing opening stdio chardev when -daemonize
is specified.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-12-30 12:48:14 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-04-19 22:55:25 +03:00
|
|
|
if (nographic) {
|
2009-12-08 15:11:42 +03:00
|
|
|
if (default_parallel)
|
|
|
|
add_device_config(DEV_PARALLEL, "null");
|
2009-12-08 15:11:44 +03:00
|
|
|
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)
|
2014-11-17 15:31:04 +03:00
|
|
|
monitor_parse("stdio", "readline", false);
|
2009-12-08 15:11:44 +03:00
|
|
|
}
|
2009-12-08 15:11:41 +03:00
|
|
|
} else {
|
|
|
|
if (default_serial)
|
|
|
|
add_device_config(DEV_SERIAL, "vc:80Cx24C");
|
2009-12-08 15:11:42 +03:00
|
|
|
if (default_parallel)
|
|
|
|
add_device_config(DEV_PARALLEL, "vc:80Cx24C");
|
2009-12-08 15:11:43 +03:00
|
|
|
if (default_monitor)
|
2014-11-17 15:31:04 +03:00
|
|
|
monitor_parse("vc:80Cx24C", "readline", false);
|
2008-08-01 19:12:34 +04:00
|
|
|
}
|
|
|
|
|
2015-02-17 10:45:06 +03:00
|
|
|
#if defined(CONFIG_VNC)
|
|
|
|
if (!QTAILQ_EMPTY(&(qemu_find_opts("vnc")->head))) {
|
|
|
|
display_remote++;
|
|
|
|
}
|
|
|
|
#endif
|
2018-02-02 14:10:22 +03:00
|
|
|
if (dpy.type == DISPLAY_TYPE_DEFAULT && !display_remote) {
|
2018-03-01 13:05:40 +03:00
|
|
|
if (!qemu_display_find_default(&dpy)) {
|
|
|
|
dpy.type = DISPLAY_TYPE_NONE;
|
|
|
|
#if defined(CONFIG_VNC)
|
|
|
|
vnc_parse("localhost:0,to=99,id=default", &error_abort);
|
2013-02-20 17:43:25 +04:00
|
|
|
#endif
|
2018-03-01 13:05:40 +03:00
|
|
|
}
|
2013-02-20 17:43:25 +04:00
|
|
|
}
|
2018-03-01 13:05:35 +03:00
|
|
|
if (dpy.type == DISPLAY_TYPE_DEFAULT) {
|
|
|
|
dpy.type = DISPLAY_TYPE_NONE;
|
2013-02-20 17:43:25 +04:00
|
|
|
}
|
|
|
|
|
2019-02-05 10:29:29 +03:00
|
|
|
if ((alt_grab || ctrl_grab) && dpy.type != DISPLAY_TYPE_SDL) {
|
|
|
|
error_report("-alt-grab and -ctrl-grab are only valid "
|
2015-10-30 18:07:52 +03:00
|
|
|
"for SDL, ignoring option");
|
2013-06-11 12:55:08 +04:00
|
|
|
}
|
2018-02-02 14:10:16 +03:00
|
|
|
if (dpy.has_window_close &&
|
2018-02-02 14:10:22 +03:00
|
|
|
(dpy.type != DISPLAY_TYPE_GTK && dpy.type != DISPLAY_TYPE_SDL)) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("-no-quit is only valid for GTK and SDL, "
|
|
|
|
"ignoring option");
|
2013-06-11 12:55:08 +04:00
|
|
|
}
|
|
|
|
|
2018-03-01 13:05:36 +03:00
|
|
|
qemu_display_early_init(&dpy);
|
2016-12-07 18:39:10 +03:00
|
|
|
qemu_console_early_init();
|
|
|
|
|
2018-04-13 16:58:40 +03:00
|
|
|
if (dpy.has_gl && dpy.gl != DISPLAYGL_MODE_OFF && display_opengl == 0) {
|
2014-11-11 18:54:45 +03:00
|
|
|
#if defined(CONFIG_OPENGL)
|
2015-10-30 18:07:54 +03:00
|
|
|
error_report("OpenGL is not supported by the display");
|
2014-11-11 18:54:45 +03:00
|
|
|
#else
|
2015-10-30 18:08:02 +03:00
|
|
|
error_report("OpenGL support is disabled");
|
2014-11-11 18:54:45 +03:00
|
|
|
#endif
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-02-20 17:43:25 +04:00
|
|
|
|
2015-11-05 21:10:31 +03:00
|
|
|
page_size_init();
|
2010-04-15 08:37:55 +04:00
|
|
|
socket_init();
|
|
|
|
|
2018-10-17 11:26:43 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("object"),
|
|
|
|
user_creatable_add_opts_foreach,
|
|
|
|
object_create_initial, &error_fatal);
|
2015-03-13 13:07:24 +03:00
|
|
|
|
2018-10-17 11:26:44 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("chardev"),
|
|
|
|
chardev_init_func, NULL, &error_fatal);
|
2019-05-14 17:30:14 +03:00
|
|
|
/* now chardevs have been created we may have semihosting to connect */
|
|
|
|
qemu_semihosting_connect_chardevs();
|
2015-11-25 13:52:28 +03:00
|
|
|
|
2010-06-15 00:34:41 +04:00
|
|
|
#ifdef CONFIG_VIRTFS
|
2018-10-17 11:26:55 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("fsdev"),
|
|
|
|
fsdev_init_func, NULL, &error_fatal);
|
2010-04-29 16:14:43 +04:00
|
|
|
#endif
|
2009-12-08 15:11:36 +03:00
|
|
|
|
2015-03-13 15:35:14 +03:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("device"),
|
|
|
|
device_help_func, NULL, NULL)) {
|
2012-08-09 22:47:40 +04:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2019-03-08 16:14:40 +03:00
|
|
|
/*
|
|
|
|
* Note: we need to create block backends before
|
|
|
|
* machine_set_property(), so machine properties can refer to
|
2019-04-01 12:08:23 +03:00
|
|
|
* them.
|
2019-03-08 16:14:40 +03:00
|
|
|
*/
|
|
|
|
configure_blockdev(&bdo_queue, machine_class, snapshot);
|
|
|
|
|
2014-05-26 16:40:58 +04:00
|
|
|
machine_opts = qemu_get_machine_opts();
|
2018-10-17 11:26:45 +03:00
|
|
|
qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
|
|
|
|
&error_fatal);
|
2019-03-04 13:13:35 +03:00
|
|
|
current_machine->ram_size = ram_size;
|
|
|
|
current_machine->maxram_size = maxram_size;
|
|
|
|
current_machine->ram_slots = ram_slots;
|
2014-05-26 16:40:58 +04:00
|
|
|
|
2019-04-01 12:08:26 +03:00
|
|
|
/*
|
|
|
|
* Note: uses machine properties such as kernel-irqchip, must run
|
|
|
|
* after machine_set_property().
|
|
|
|
*/
|
2019-11-13 11:59:04 +03:00
|
|
|
configure_accelerators(argv[0]);
|
2009-09-18 09:41:23 +04:00
|
|
|
|
2019-04-01 12:08:26 +03:00
|
|
|
/*
|
|
|
|
* Beware, QOM objects created before this point miss global and
|
|
|
|
* compat properties.
|
|
|
|
*
|
|
|
|
* Global properties get set up by qdev_prop_register_global(),
|
|
|
|
* called from user_register_global_props(), and certain option
|
|
|
|
* desugaring. Also in CPU feature desugaring (buried in
|
2019-04-17 05:59:40 +03:00
|
|
|
* parse_cpu_option()), which happens below this point, but may
|
2019-04-01 12:08:26 +03:00
|
|
|
* only target the CPU type, which can only be created after
|
2019-04-17 05:59:40 +03:00
|
|
|
* parse_cpu_option() returned the type.
|
2019-04-01 12:08:26 +03:00
|
|
|
*
|
|
|
|
* Machine compat properties: object_set_machine_compat_props().
|
|
|
|
* Accelerator compat props: object_set_accelerator_compat_props(),
|
|
|
|
* called from configure_accelerator().
|
|
|
|
*/
|
|
|
|
|
2018-06-25 12:05:12 +03:00
|
|
|
if (!qtest_enabled() && machine_class->deprecation_reason) {
|
|
|
|
error_report("Machine type '%s' is deprecated: %s",
|
|
|
|
machine_class->name, machine_class->deprecation_reason);
|
|
|
|
}
|
|
|
|
|
2019-04-01 12:08:23 +03:00
|
|
|
/*
|
2019-04-01 12:08:26 +03:00
|
|
|
* Note: creates a QOM object, must run only after global and
|
|
|
|
* compat properties have been set up.
|
2019-04-01 12:08:23 +03:00
|
|
|
*/
|
|
|
|
migration_object_init();
|
|
|
|
|
2015-11-25 13:52:28 +03:00
|
|
|
if (qtest_chrdev) {
|
2019-08-05 06:13:01 +03:00
|
|
|
qtest_server_init(qtest_chrdev, qtest_log, &error_fatal);
|
2015-11-25 13:52:28 +03:00
|
|
|
}
|
|
|
|
|
2013-07-04 17:09:22 +04:00
|
|
|
machine_opts = qemu_get_machine_opts();
|
|
|
|
kernel_filename = qemu_opt_get(machine_opts, "kernel");
|
|
|
|
initrd_filename = qemu_opt_get(machine_opts, "initrd");
|
|
|
|
kernel_cmdline = qemu_opt_get(machine_opts, "append");
|
2013-10-15 18:57:45 +04:00
|
|
|
bios_name = qemu_opt_get(machine_opts, "firmware");
|
2012-02-23 02:40:00 +04:00
|
|
|
|
vl: Fix -boot order and once regressions, and related bugs
Option "once" sets up a different boot order just for the initial
boot. Boot order reverts back to normal on reset. Option "order"
changes the normal boot order.
The reversal is implemented by reset handler restore_boot_devices(),
which takes the boot order to revert to as argument.
restore_boot_devices() does nothing on its first call, because that
must be the initial machine reset. On its second call, it changes the
boot order back, and unregisters itself.
Because we register the handler right when -boot gets parsed, we can
revert to an incorrect normal boot order, and multiple -boot can
interact in funny ways.
Here's how things work without -boot once or order:
* boot_devices is "".
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "". machine->init() configures firmware
accordingly. For PC machines, machine->boot_order is "cad", and
pc_cmos_init() writes it to RTC CMOS, where SeaBIOS picks it up.
Now consider -boot order=:
* boot_devices is "".
* -boot order= sets boot_devices to "" (no change).
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "", as above.
Bug: -boot order= has no effect. Broken in commit e4ada29e.
Next, consider -boot once=a:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* main() passes boot_devices "a" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "a".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of machine->boot_order. The
actual boot order depends on how firmware interprets "". Broken
in commit e4ada29e.
Next, consider -boot once=a -boot order=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot order=c sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "c".
Bug: it should be "a". I figure this has always been broken.
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of "c". I figure this has
always been broken, just differently broken before commit
e4ada29e.
Next, consider -boot once=a -boot once=b -boot once=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot once=b registers restore_boot_devices() with argument "a", and
sets boot_devices to "b".
* -boot once=c registers restore_boot_devices() with argument "b", and
sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
- restore_boot_devices() gets called with argument "a". Calls
qemu_boot_set("a") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
- restore_boot_devices() gets called with argument "b". Calls
qemu_boot_set("b") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
* Machine boots, boot order is "b".
Bug: should really be "c", because that came last, and for all other
-boot options, the last one wins. I figure this was broken some
time before commit 37905d6a, and fixed there only for a single
occurence of "once".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Same bug as above: boot order reverts to "" instead of
machine->boot_order.
Fix by acting upon -boot options order, once and menu only after
option parsing is complete, and the machine is known. This is how the
other -boot options work already.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1371208516-7857-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-14 15:15:03 +04:00
|
|
|
opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL);
|
|
|
|
if (opts) {
|
2015-02-03 14:31:09 +03:00
|
|
|
boot_order = qemu_opt_get(opts, "order");
|
|
|
|
if (boot_order) {
|
2015-09-11 16:04:45 +03:00
|
|
|
validate_bootdevices(boot_order, &error_fatal);
|
vl: Fix -boot order and once regressions, and related bugs
Option "once" sets up a different boot order just for the initial
boot. Boot order reverts back to normal on reset. Option "order"
changes the normal boot order.
The reversal is implemented by reset handler restore_boot_devices(),
which takes the boot order to revert to as argument.
restore_boot_devices() does nothing on its first call, because that
must be the initial machine reset. On its second call, it changes the
boot order back, and unregisters itself.
Because we register the handler right when -boot gets parsed, we can
revert to an incorrect normal boot order, and multiple -boot can
interact in funny ways.
Here's how things work without -boot once or order:
* boot_devices is "".
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "". machine->init() configures firmware
accordingly. For PC machines, machine->boot_order is "cad", and
pc_cmos_init() writes it to RTC CMOS, where SeaBIOS picks it up.
Now consider -boot order=:
* boot_devices is "".
* -boot order= sets boot_devices to "" (no change).
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "", as above.
Bug: -boot order= has no effect. Broken in commit e4ada29e.
Next, consider -boot once=a:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* main() passes boot_devices "a" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "a".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of machine->boot_order. The
actual boot order depends on how firmware interprets "". Broken
in commit e4ada29e.
Next, consider -boot once=a -boot order=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot order=c sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "c".
Bug: it should be "a". I figure this has always been broken.
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of "c". I figure this has
always been broken, just differently broken before commit
e4ada29e.
Next, consider -boot once=a -boot once=b -boot once=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot once=b registers restore_boot_devices() with argument "a", and
sets boot_devices to "b".
* -boot once=c registers restore_boot_devices() with argument "b", and
sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
- restore_boot_devices() gets called with argument "a". Calls
qemu_boot_set("a") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
- restore_boot_devices() gets called with argument "b". Calls
qemu_boot_set("b") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
* Machine boots, boot order is "b".
Bug: should really be "c", because that came last, and for all other
-boot options, the last one wins. I figure this was broken some
time before commit 37905d6a, and fixed there only for a single
occurence of "once".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Same bug as above: boot order reverts to "" instead of
machine->boot_order.
Fix by acting upon -boot options order, once and menu only after
option parsing is complete, and the machine is known. This is how the
other -boot options work already.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1371208516-7857-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-14 15:15:03 +04:00
|
|
|
}
|
|
|
|
|
2015-02-03 14:31:09 +03:00
|
|
|
boot_once = qemu_opt_get(opts, "once");
|
|
|
|
if (boot_once) {
|
2015-09-11 16:04:45 +03:00
|
|
|
validate_bootdevices(boot_once, &error_fatal);
|
vl: Fix -boot order and once regressions, and related bugs
Option "once" sets up a different boot order just for the initial
boot. Boot order reverts back to normal on reset. Option "order"
changes the normal boot order.
The reversal is implemented by reset handler restore_boot_devices(),
which takes the boot order to revert to as argument.
restore_boot_devices() does nothing on its first call, because that
must be the initial machine reset. On its second call, it changes the
boot order back, and unregisters itself.
Because we register the handler right when -boot gets parsed, we can
revert to an incorrect normal boot order, and multiple -boot can
interact in funny ways.
Here's how things work without -boot once or order:
* boot_devices is "".
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "". machine->init() configures firmware
accordingly. For PC machines, machine->boot_order is "cad", and
pc_cmos_init() writes it to RTC CMOS, where SeaBIOS picks it up.
Now consider -boot order=:
* boot_devices is "".
* -boot order= sets boot_devices to "" (no change).
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "", as above.
Bug: -boot order= has no effect. Broken in commit e4ada29e.
Next, consider -boot once=a:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* main() passes boot_devices "a" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "a".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of machine->boot_order. The
actual boot order depends on how firmware interprets "". Broken
in commit e4ada29e.
Next, consider -boot once=a -boot order=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot order=c sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "c".
Bug: it should be "a". I figure this has always been broken.
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of "c". I figure this has
always been broken, just differently broken before commit
e4ada29e.
Next, consider -boot once=a -boot once=b -boot once=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot once=b registers restore_boot_devices() with argument "a", and
sets boot_devices to "b".
* -boot once=c registers restore_boot_devices() with argument "b", and
sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
- restore_boot_devices() gets called with argument "a". Calls
qemu_boot_set("a") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
- restore_boot_devices() gets called with argument "b". Calls
qemu_boot_set("b") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
* Machine boots, boot order is "b".
Bug: should really be "c", because that came last, and for all other
-boot options, the last one wins. I figure this was broken some
time before commit 37905d6a, and fixed there only for a single
occurence of "once".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Same bug as above: boot order reverts to "" instead of
machine->boot_order.
Fix by acting upon -boot options order, once and menu only after
option parsing is complete, and the machine is known. This is how the
other -boot options work already.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1371208516-7857-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-14 15:15:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
boot_menu = qemu_opt_get_bool(opts, "menu", boot_menu);
|
2013-12-09 15:53:15 +04:00
|
|
|
boot_strict = qemu_opt_get_bool(opts, "strict", false);
|
vl: Fix -boot order and once regressions, and related bugs
Option "once" sets up a different boot order just for the initial
boot. Boot order reverts back to normal on reset. Option "order"
changes the normal boot order.
The reversal is implemented by reset handler restore_boot_devices(),
which takes the boot order to revert to as argument.
restore_boot_devices() does nothing on its first call, because that
must be the initial machine reset. On its second call, it changes the
boot order back, and unregisters itself.
Because we register the handler right when -boot gets parsed, we can
revert to an incorrect normal boot order, and multiple -boot can
interact in funny ways.
Here's how things work without -boot once or order:
* boot_devices is "".
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "". machine->init() configures firmware
accordingly. For PC machines, machine->boot_order is "cad", and
pc_cmos_init() writes it to RTC CMOS, where SeaBIOS picks it up.
Now consider -boot order=:
* boot_devices is "".
* -boot order= sets boot_devices to "" (no change).
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "", as above.
Bug: -boot order= has no effect. Broken in commit e4ada29e.
Next, consider -boot once=a:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* main() passes boot_devices "a" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "a".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of machine->boot_order. The
actual boot order depends on how firmware interprets "". Broken
in commit e4ada29e.
Next, consider -boot once=a -boot order=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot order=c sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "c".
Bug: it should be "a". I figure this has always been broken.
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of "c". I figure this has
always been broken, just differently broken before commit
e4ada29e.
Next, consider -boot once=a -boot once=b -boot once=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot once=b registers restore_boot_devices() with argument "a", and
sets boot_devices to "b".
* -boot once=c registers restore_boot_devices() with argument "b", and
sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
- restore_boot_devices() gets called with argument "a". Calls
qemu_boot_set("a") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
- restore_boot_devices() gets called with argument "b". Calls
qemu_boot_set("b") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
* Machine boots, boot order is "b".
Bug: should really be "c", because that came last, and for all other
-boot options, the last one wins. I figure this was broken some
time before commit 37905d6a, and fixed there only for a single
occurence of "once".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Same bug as above: boot order reverts to "" instead of
machine->boot_order.
Fix by acting upon -boot options order, once and menu only after
option parsing is complete, and the machine is known. This is how the
other -boot options work already.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1371208516-7857-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-14 15:15:03 +04:00
|
|
|
}
|
|
|
|
|
2015-02-03 14:31:09 +03:00
|
|
|
if (!boot_order) {
|
|
|
|
boot_order = machine_class->default_boot_order;
|
|
|
|
}
|
|
|
|
|
2012-02-08 09:41:39 +04:00
|
|
|
if (!kernel_cmdline) {
|
|
|
|
kernel_cmdline = "";
|
2014-05-26 16:40:58 +04:00
|
|
|
current_machine->kernel_cmdline = (char *)kernel_cmdline;
|
2012-02-08 09:41:39 +04:00
|
|
|
}
|
|
|
|
|
2003-10-01 01:07:02 +04:00
|
|
|
linux_boot = (kernel_filename != NULL);
|
2007-11-17 15:12:29 +03:00
|
|
|
|
2008-07-03 14:01:15 +04:00
|
|
|
if (!linux_boot && *kernel_cmdline != '\0') {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("-append only allowed with -kernel option");
|
2008-07-03 14:01:15 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!linux_boot && initrd_filename != NULL) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("-initrd only allowed with -kernel option");
|
2008-07-03 14:01:15 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2015-06-19 16:17:45 +03:00
|
|
|
if (semihosting_enabled() && !semihosting_get_argc() && kernel_filename) {
|
|
|
|
/* fall back to the -kernel/-append */
|
|
|
|
semihosting_arg_fallback(kernel_filename, kernel_cmdline);
|
|
|
|
}
|
|
|
|
|
2012-03-14 22:33:37 +04:00
|
|
|
/* spice needs the timers to be initialized by this point */
|
|
|
|
qemu_spice_init();
|
|
|
|
|
2014-09-01 09:34:49 +04:00
|
|
|
cpu_ticks_init();
|
2017-02-27 20:09:01 +03:00
|
|
|
|
2016-05-12 17:17:16 +03:00
|
|
|
if (default_net) {
|
|
|
|
QemuOptsList *net = qemu_find_opts("net");
|
|
|
|
qemu_opts_set(net, NULL, "type", "nic", &error_abort);
|
|
|
|
#ifdef CONFIG_SLIRP
|
|
|
|
qemu_opts_set(net, NULL, "type", "user", &error_abort);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-02-21 13:18:30 +03:00
|
|
|
if (net_init_clients(&err) < 0) {
|
|
|
|
error_report_err(err);
|
2009-10-06 15:17:16 +04:00
|
|
|
exit(1);
|
2004-04-03 01:21:32 +04:00
|
|
|
}
|
2003-06-25 04:07:40 +04:00
|
|
|
|
2018-10-17 11:26:43 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("object"),
|
|
|
|
user_creatable_add_opts_foreach,
|
|
|
|
object_create_delayed, &error_fatal);
|
2015-10-07 06:52:13 +03:00
|
|
|
|
2018-10-17 11:26:53 +03:00
|
|
|
tpm_init();
|
Support for TPM command line options
This patch adds support for TPM command line options.
The command line options supported here are
./qemu-... -tpmdev passthrough,path=<path to TPM device>,id=<id>
-device tpm-tis,tpmdev=<id>,id=<other id>
and
./qemu-... -tpmdev help
where the latter works similar to -soundhw help and shows a list of
available TPM backends (for example 'passthrough').
Using the type parameter, the backend is chosen, i.e., 'passthrough' for the
passthrough driver. The interpretation of the other parameters along
with determining whether enough parameters were provided is pushed into
the backend driver, which needs to implement the interface function
'create' and return a TPMDriverOpts structure if the VM can be started or
'NULL' if not enough or bad parameters were provided.
Monitor support for 'info tpm' has been added. It for example prints the
following:
(qemu) info tpm
TPM devices:
tpm0: model=tpm-tis
\ tpm0: type=passthrough,path=/dev/tpm0,cancel-path=/sys/devices/pnp0/00:09/cancel
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
Reviewed-by: Joel Schopp <jschopp@linux.vnet.ibm.com>
Message-id: 1361987275-26289-2-git-send-email-stefanb@linux.vnet.ibm.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-02-27 21:47:49 +04:00
|
|
|
|
2011-07-20 12:17:44 +04:00
|
|
|
if (!xen_enabled()) {
|
|
|
|
/* On 32-bit hosts, QEMU is limited by virtual address space */
|
|
|
|
if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("at most 2047 MB RAM can be simulated");
|
2011-07-20 12:17:44 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
2007-01-05 20:39:04 +03:00
|
|
|
|
2009-11-02 16:40:58 +03:00
|
|
|
blk_mig_init();
|
2014-03-19 22:32:30 +04:00
|
|
|
ram_mig_init();
|
2018-03-13 22:34:01 +03:00
|
|
|
dirty_bitmap_mig_init();
|
2009-11-02 16:40:58 +03:00
|
|
|
|
2018-10-17 11:26:46 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("mon"),
|
|
|
|
mon_init_func, NULL, &error_fatal);
|
2010-04-06 18:55:53 +04:00
|
|
|
|
2019-11-04 23:42:30 +03:00
|
|
|
/* connect semihosting console input if requested */
|
|
|
|
qemu_semihosting_console_init();
|
|
|
|
|
2009-12-08 15:11:41 +03:00
|
|
|
if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
|
|
|
|
exit(1);
|
2009-12-08 15:11:42 +03:00
|
|
|
if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
|
|
|
|
exit(1);
|
debugcon: support for debugging consoles (e.g. Bochs port 0xe9)
Add generic support for debugging consoles (simple I/O ports which
when written to cause debugging output to be written to a target.)
The current implementation matches Bochs' port 0xe9, allowing the same
debugging code to be used for both Bochs and Qemu.
There is no vm state associated with the debugging port, simply
because it has none -- the entire interface is a single, stateless,
write-only port.
Most of the code was cribbed from the serial port driver.
v2: removed non-ISA variants (they can be introduced when/if someone
wants them, using code from the serial port); added configurable
readback (Bochs returns 0xe9 on a read from this register, mimic that
by default) This retains the apparently somewhat controversial user
friendly option, however.
v3: reimplemented the user friendly option as a synthetic option
("-debugcon foo" basically ends up being a parser-level shorthand for
"-chardev stdio,id=debugcon -device isa-debugcon,chardev=debugcon") --
this dramatically reduced the complexity while keeping the same level
of user friendliness.
v4: spaces, not tabs.
v5: update to match current top of tree. Calling qemu_chr_open()
already during parsing no longer works; defer until we are parsing the
other console-like devices.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-30 00:51:36 +03:00
|
|
|
if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
|
|
|
|
exit(1);
|
2009-01-16 23:23:27 +03:00
|
|
|
|
2012-05-10 11:39:17 +04:00
|
|
|
/* If no default VGA is requested, the default is "none". */
|
2012-09-10 03:01:44 +04:00
|
|
|
if (default_vga) {
|
2019-04-12 18:27:13 +03:00
|
|
|
vga_model = get_default_vga_model(machine_class);
|
2011-09-27 23:15:42 +04:00
|
|
|
}
|
2014-03-10 18:37:40 +04:00
|
|
|
if (vga_model) {
|
2019-04-12 18:27:13 +03:00
|
|
|
select_vgahw(machine_class, vga_model);
|
2014-03-10 18:37:40 +04:00
|
|
|
}
|
2011-09-27 23:15:42 +04:00
|
|
|
|
2009-08-21 12:31:34 +04:00
|
|
|
if (watchdog) {
|
|
|
|
i = select_watchdog(watchdog);
|
|
|
|
if (i > 0)
|
|
|
|
exit (i == 1 ? 1 : 0);
|
|
|
|
}
|
|
|
|
|
2015-09-17 19:24:44 +03:00
|
|
|
/* This checkpoint is required by replay to separate prior clock
|
|
|
|
reading from the other reads, because timer polling functions query
|
|
|
|
clock values from the log. */
|
|
|
|
replay_checkpoint(CHECKPOINT_INIT);
|
2011-12-20 02:37:46 +04:00
|
|
|
qdev_machine_init();
|
|
|
|
|
2014-05-07 18:42:57 +04:00
|
|
|
current_machine->boot_order = boot_order;
|
|
|
|
|
2017-09-13 19:04:55 +03:00
|
|
|
/* parse features once if machine provides default cpu_type */
|
2018-02-07 13:40:26 +03:00
|
|
|
current_machine->cpu_type = machine_class->default_cpu_type;
|
2019-04-17 05:59:40 +03:00
|
|
|
if (cpu_option) {
|
|
|
|
current_machine->cpu_type = parse_cpu_option(cpu_option);
|
2017-09-13 19:04:55 +03:00
|
|
|
}
|
2018-01-10 18:22:50 +03:00
|
|
|
parse_numa_opts(current_machine);
|
2017-09-13 19:04:55 +03:00
|
|
|
|
2018-05-11 20:24:43 +03:00
|
|
|
/* do monitor/qmp handling at preconfig state if requested */
|
2020-02-20 07:10:58 +03:00
|
|
|
qemu_main_loop();
|
2018-05-11 20:24:43 +03:00
|
|
|
|
2019-03-09 01:34:15 +03:00
|
|
|
audio_init_audiodevs();
|
|
|
|
|
2018-05-11 20:24:43 +03:00
|
|
|
/* from here on runstate is RUN_STATE_PRELAUNCH */
|
2017-05-10 14:29:58 +03:00
|
|
|
machine_run_board_init(current_machine);
|
2009-01-16 22:04:14 +03:00
|
|
|
|
2014-09-23 14:42:24 +04:00
|
|
|
realtime_init();
|
|
|
|
|
2017-05-08 23:57:34 +03:00
|
|
|
soundhw_init();
|
2013-04-18 20:44:04 +04:00
|
|
|
|
2017-01-10 13:59:57 +03:00
|
|
|
if (hax_enabled()) {
|
|
|
|
hax_sync_vcpus();
|
|
|
|
}
|
|
|
|
|
2018-10-17 11:26:47 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("fw_cfg"),
|
|
|
|
parse_fw_cfg, fw_cfg_find(), &error_fatal);
|
2015-04-29 18:21:53 +03:00
|
|
|
|
2009-01-16 22:04:14 +03:00
|
|
|
/* init USB devices */
|
2016-06-08 23:50:25 +03:00
|
|
|
if (machine_usb(current_machine)) {
|
Don't exit() in config_error()
Propagating errors up the call chain is tedious. In startup code, we
can take a shortcut: terminate the program. This is wrong elsewhere,
the monitor in particular.
config_error() tries to cater for both customers: it terminates the
program unless its mon parameter tells it it's working for the
monitor.
Its users need to return status anyway (unless passing a null mon
argument, which none do), which their users need to check. So this
automatic exit buys us exactly nothing useful. Only the dangerous
delusion that we can get away without returning status. Some of its
users fell for that. Their callers continue executing after failure
when working for the monitor.
This bites monitor command host_net_add in two places:
* net_slirp_init() continues after slirp_hostfwd(), slirp_guestfwd(),
or slirp_smb() failed, and may end up reporting success. This
happens for "host_net_add user guestfwd=foo": it complains about the
invalid guest forwarding rule, then happily creates the user network
without guest forwarding.
* net_client_init() can't detect slirp_guestfwd() failure, and gets
fooled by net_slirp_init() lying about success. Suppresses its
"Could not initialize device" message.
Add the missing error reporting, make sure errors are checked, and
drop the exit() from config_error().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-10-06 15:16:57 +04:00
|
|
|
if (foreach_device_config(DEV_USB, usb_parse) < 0)
|
|
|
|
exit(1);
|
2009-01-16 22:04:14 +03:00
|
|
|
}
|
|
|
|
|
2009-07-15 15:59:26 +04:00
|
|
|
/* init generic devices */
|
2016-04-07 17:12:58 +03:00
|
|
|
rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE);
|
2018-10-17 11:26:48 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("device"),
|
|
|
|
device_init_func, NULL, &error_fatal);
|
2017-01-17 17:42:31 +03:00
|
|
|
|
2017-02-01 05:29:38 +03:00
|
|
|
cpu_synchronize_all_post_init();
|
|
|
|
|
2016-04-07 17:12:58 +03:00
|
|
|
rom_reset_order_override();
|
2009-07-15 15:59:26 +04:00
|
|
|
|
2014-10-01 22:19:24 +04:00
|
|
|
/* Did we create any drives that we failed to create a device for? */
|
|
|
|
drive_check_orphaned();
|
|
|
|
|
2016-05-12 17:17:16 +03:00
|
|
|
/* 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.
|
|
|
|
*/
|
2018-08-16 14:35:52 +03:00
|
|
|
if (!default_net && (!qtest_enabled() || has_defaults)) {
|
2016-05-12 17:17:16 +03:00
|
|
|
net_check_clients();
|
|
|
|
}
|
|
|
|
|
2015-02-03 14:31:09 +03:00
|
|
|
if (boot_once) {
|
2016-01-14 18:02:12 +03:00
|
|
|
qemu_boot_set(boot_once, &error_fatal);
|
2015-02-03 14:31:09 +03:00
|
|
|
qemu_register_reset(restore_boot_order, g_strdup(boot_order));
|
|
|
|
}
|
|
|
|
|
2010-08-25 12:51:06 +04:00
|
|
|
/* init local displays */
|
2018-03-01 13:05:38 +03:00
|
|
|
ds = init_displaystate();
|
|
|
|
qemu_display_init(ds, &dpy);
|
2010-08-25 12:51:06 +04:00
|
|
|
|
2011-03-31 13:27:23 +04:00
|
|
|
/* must be after terminal init, SDL library changes signal handlers */
|
|
|
|
os_setup_signal_handling();
|
|
|
|
|
2010-08-25 12:51:06 +04:00
|
|
|
/* init remote displays */
|
2016-06-16 04:59:10 +03:00
|
|
|
#ifdef CONFIG_VNC
|
2015-03-13 15:35:14 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("vnc"),
|
2018-10-17 11:26:51 +03:00
|
|
|
vnc_init_func, NULL, &error_fatal);
|
2016-06-16 04:59:10 +03:00
|
|
|
#endif
|
2016-04-19 22:55:18 +03:00
|
|
|
|
2013-10-12 00:39:59 +04:00
|
|
|
if (using_spice) {
|
|
|
|
qemu_spice_display_init();
|
2010-08-25 17:32:06 +04:00
|
|
|
}
|
2008-08-22 00:08:03 +04:00
|
|
|
|
2012-02-07 18:09:13 +04:00
|
|
|
if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
|
2009-04-05 22:43:41 +04:00
|
|
|
exit(1);
|
2007-07-02 17:20:17 +04:00
|
|
|
}
|
|
|
|
|
2009-09-25 23:42:41 +04:00
|
|
|
qdev_machine_creation_done();
|
|
|
|
|
2010-12-20 08:33:35 +03:00
|
|
|
/* TODO: once all bus devices are qdevified, this should be done
|
|
|
|
* when bus is created by qdev.c */
|
2020-01-30 19:02:05 +03:00
|
|
|
/*
|
|
|
|
* TODO: If we had a main 'reset container' that the whole system
|
|
|
|
* lived in, we could reset that using the multi-phase reset
|
|
|
|
* APIs. For the moment, we just reset the sysbus, which will cause
|
|
|
|
* all devices hanging off it (and all their child buses, recursively)
|
|
|
|
* to be reset. Note that this will *not* reset any Device objects
|
|
|
|
* which are not attached to some part of the qbus tree!
|
|
|
|
*/
|
|
|
|
qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
|
2010-12-08 14:35:08 +03:00
|
|
|
qemu_run_machine_init_done_notifiers();
|
|
|
|
|
2015-06-16 19:07:54 +03:00
|
|
|
if (rom_check_and_register_reset() != 0) {
|
2015-10-30 18:07:52 +03:00
|
|
|
error_report("rom check and register reset failed");
|
2015-06-16 19:07:54 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
2013-07-24 19:56:08 +04:00
|
|
|
|
2015-09-17 19:25:07 +03:00
|
|
|
replay_start();
|
|
|
|
|
2015-09-17 19:24:44 +03:00
|
|
|
/* This checkpoint is required by replay to separate prior clock
|
|
|
|
reading from the other reads, because timer polling functions query
|
|
|
|
clock values from the log. */
|
|
|
|
replay_checkpoint(CHECKPOINT_RESET);
|
shutdown: Prepare for use of an enum in reset/shutdown_request
We want to track why a guest was shutdown; in particular, being able
to tell the difference between a guest request (such as ACPI request)
and host request (such as SIGINT) will prove useful to libvirt.
Since all requests eventually end up changing shutdown_requested in
vl.c, the logical change is to make that value track the reason,
rather than its current 0/1 contents.
Since command-line options control whether a reset request is turned
into a shutdown request instead, the same treatment is given to
reset_requested.
This patch adds an internal enum ShutdownCause that describes reasons
that a shutdown can be requested, and changes qemu_system_reset() to
pass the reason through, although for now nothing is actually changed
with regards to what gets reported. The enum could be exported via
QAPI at a later date, if deemed necessary, but for now, there has not
been a request to expose that much detail to end clients.
For the most part, we turn 0 into SHUTDOWN_CAUSE_NONE, and 1 into
SHUTDOWN_CAUSE_HOST_ERROR; the only specific case where we have enough
information right now to use a different value is when we are reacting
to a host signal. It will take a further patch to edit all call-sites
that can trigger a reset or shutdown request to properly pass in any
other reasons; this patch includes TODOs to point such places out.
qemu_system_reset() trades its 'bool report' parameter for a
'ShutdownCause reason', with all non-zero values having the same
effect; this lets us get rid of the weird #defines for VMRESET_*
as synonyms for bools.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170515214114.15442-3-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-05-16 00:41:11 +03:00
|
|
|
qemu_system_reset(SHUTDOWN_CAUSE_NONE);
|
2015-07-10 15:51:58 +03:00
|
|
|
register_global_state();
|
2018-09-12 11:19:39 +03:00
|
|
|
if (loadvm) {
|
2017-04-18 19:12:35 +03:00
|
|
|
Error *local_err = NULL;
|
2017-04-20 15:25:55 +03:00
|
|
|
if (load_snapshot(loadvm, &local_err) < 0) {
|
2017-04-18 19:12:35 +03:00
|
|
|
error_report_err(local_err);
|
2009-08-20 21:42:22 +04:00
|
|
|
autostart = 0;
|
2018-09-03 19:26:13 +03:00
|
|
|
exit(1);
|
2009-08-20 21:42:22 +04:00
|
|
|
}
|
|
|
|
}
|
2018-09-12 11:19:39 +03:00
|
|
|
if (replay_mode != REPLAY_MODE_NONE) {
|
|
|
|
replay_vmstate_init();
|
|
|
|
}
|
2004-10-03 17:29:03 +04:00
|
|
|
|
2014-08-08 23:03:30 +04:00
|
|
|
qdev_prop_check_globals();
|
2014-06-20 17:26:08 +04:00
|
|
|
if (vmstate_dump_file) {
|
|
|
|
/* dump and exit */
|
|
|
|
dump_vmstate_json_to_file(vmstate_dump_file);
|
2020-02-20 07:10:58 +03:00
|
|
|
exit(0);
|
2014-06-20 17:26:08 +04:00
|
|
|
}
|
2014-05-05 22:03:06 +04:00
|
|
|
|
2009-07-25 00:20:23 +04:00
|
|
|
if (incoming) {
|
2012-10-02 20:21:18 +04:00
|
|
|
Error *local_err = NULL;
|
|
|
|
qemu_start_incoming_migration(incoming, &local_err);
|
|
|
|
if (local_err) {
|
2015-12-18 18:35:14 +03:00
|
|
|
error_reportf_err(local_err, "-incoming %s: ", incoming);
|
2012-10-02 20:21:18 +04:00
|
|
|
exit(1);
|
2010-06-09 16:10:54 +04:00
|
|
|
}
|
2009-08-09 15:39:20 +04:00
|
|
|
} else if (autostart) {
|
2009-03-06 02:01:01 +03:00
|
|
|
vm_start();
|
2009-08-09 15:39:20 +04:00
|
|
|
}
|
2006-12-21 22:46:43 +03:00
|
|
|
|
2018-03-09 15:02:50 +03:00
|
|
|
accel_setup_post(current_machine);
|
2010-06-10 13:42:28 +04:00
|
|
|
os_setup_post();
|
2006-12-22 05:11:31 +03:00
|
|
|
|
2020-02-20 07:10:58 +03:00
|
|
|
return;
|
|
|
|
}
|
2018-03-07 17:42:05 +03:00
|
|
|
|
2020-02-20 07:10:58 +03:00
|
|
|
void qemu_cleanup(void)
|
|
|
|
{
|
2018-03-20 12:39:33 +03:00
|
|
|
gdbserver_cleanup();
|
|
|
|
|
2019-02-27 19:49:00 +03:00
|
|
|
/*
|
|
|
|
* cleaning up the migration object cancels any existing migration
|
|
|
|
* try to do this early so that it also stops using devices.
|
|
|
|
*/
|
|
|
|
migration_shutdown();
|
|
|
|
|
2019-06-13 01:08:38 +03:00
|
|
|
/*
|
|
|
|
* We must cancel all block jobs while the block layer is drained,
|
|
|
|
* or cancelling will be affected by throttling and thus may block
|
|
|
|
* for an extended period of time.
|
|
|
|
* vm_shutdown() will bdrv_drain_all(), so we may as well include
|
|
|
|
* it in the drained section.
|
|
|
|
* We do not need to end this section, because we do not want any
|
|
|
|
* requests happening from here on anyway.
|
|
|
|
*/
|
|
|
|
bdrv_drain_all_begin();
|
|
|
|
|
2018-03-07 17:42:05 +03:00
|
|
|
/* No more vcpu or device emulation activity beyond this point */
|
|
|
|
vm_shutdown();
|
2019-09-17 14:58:13 +03:00
|
|
|
replay_finish();
|
2018-03-07 17:42:05 +03:00
|
|
|
|
2018-05-16 14:46:37 +03:00
|
|
|
job_cancel_sync_all();
|
2017-07-13 22:01:16 +03:00
|
|
|
bdrv_close_all();
|
2018-02-01 14:07:08 +03:00
|
|
|
|
2011-07-27 14:04:55 +04:00
|
|
|
res_free();
|
2007-10-22 03:20:45 +04:00
|
|
|
|
char: do not use atexit cleanup handler
It turns out qemu is calling exit() in various places from various
threads without taking much care of resources state. The atexit()
cleanup handlers cannot easily destroy resources that are in use (by
the same thread or other).
Since c1111a24a3, TCG arm guests run into the following abort() when
running tests, the chardev mutex is locked during the write, so
qemu_mutex_destroy() returns an error:
#0 0x00007fffdbb806f5 in raise () at /lib64/libc.so.6
#1 0x00007fffdbb822fa in abort () at /lib64/libc.so.6
#2 0x00005555557616fe in error_exit (err=<optimized out>, msg=msg@entry=0x555555c38c30 <__func__.14622> "qemu_mutex_destroy")
at /home/drjones/code/qemu/util/qemu-thread-posix.c:39
#3 0x0000555555b0be20 in qemu_mutex_destroy (mutex=mutex@entry=0x5555566aa0e0) at /home/drjones/code/qemu/util/qemu-thread-posix.c:57
#4 0x00005555558aab00 in qemu_chr_free_common (chr=0x5555566aa0e0) at /home/drjones/code/qemu/qemu-char.c:4029
#5 0x00005555558b05f9 in qemu_chr_delete (chr=<optimized out>) at /home/drjones/code/qemu/qemu-char.c:4038
#6 0x00005555558b05f9 in qemu_chr_delete (chr=<optimized out>) at /home/drjones/code/qemu/qemu-char.c:4044
#7 0x00005555558b062c in qemu_chr_cleanup () at /home/drjones/code/qemu/qemu-char.c:4557
#8 0x00007fffdbb851e8 in __run_exit_handlers () at /lib64/libc.so.6
#9 0x00007fffdbb85235 in () at /lib64/libc.so.6
#10 0x00005555558d1b39 in testdev_write (testdev=0x5555566aa0a0) at /home/drjones/code/qemu/backends/testdev.c:71
#11 0x00005555558d1b39 in testdev_write (chr=<optimized out>, buf=0x7fffc343fd9a "", len=0) at /home/drjones/code/qemu/backends/testdev.c:95
#12 0x00005555558adced in qemu_chr_fe_write (s=0x5555566aa0e0, buf=buf@entry=0x7fffc343fd98 "0q", len=len@entry=2) at /home/drjones/code/qemu/qemu-char.c:282
Instead of using a atexit() handler, only run the chardev cleanup as
initially proposed at the end of main(), where there are less chances
(hic) of conflicts or other races.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reported-by: Andrew Jones <drjones@redhat.com>
Message-Id: <20160704153823.16879-1-marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-07-04 18:38:23 +03:00
|
|
|
/* vhost-user must be cleaned up before chardevs. */
|
2017-09-29 14:10:21 +03:00
|
|
|
tpm_cleanup();
|
2016-07-08 18:28:34 +03:00
|
|
|
net_cleanup();
|
2016-08-01 14:23:43 +03:00
|
|
|
audio_cleanup();
|
monitor: fix crash when leaving qemu with spice audio
Since aa5cb7f5e, the chardevs are being cleaned up when leaving
qemu. However, the monitor has still references to them, which may
lead to crashes when running atexit() and trying to send monitor
events:
#0 0x00007fffdb18f6f5 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#1 0x00007fffdb1912fa in __GI_abort () at abort.c:89
#2 0x0000555555c263e7 in error_exit (err=22, msg=0x555555d47980 <__func__.13537> "qemu_mutex_lock") at util/qemu-thread-posix.c:39
#3 0x0000555555c26488 in qemu_mutex_lock (mutex=0x5555567a2420) at util/qemu-thread-posix.c:66
#4 0x00005555558c52db in qemu_chr_fe_write (s=0x5555567a2420, buf=0x55555740dc40 "{\"timestamp\": {\"seconds\": 1470041716, \"microseconds\": 989699}, \"event\": \"SPICE_DISCONNECTED\", \"data\": {\"server\": {\"port\": \"5900\", \"family\": \"ipv4\", \"host\": \"127.0.0.1\"}, \"client\": {\"port\": \"40272\", \"f"..., len=240) at qemu-char.c:280
#5 0x0000555555787cad in monitor_flush_locked (mon=0x5555567bd9e0) at /home/elmarco/src/qemu/monitor.c:311
#6 0x0000555555787e46 in monitor_puts (mon=0x5555567bd9e0, str=0x5555567a44ef "") at /home/elmarco/src/qemu/monitor.c:353
#7 0x00005555557880fe in monitor_json_emitter (mon=0x5555567bd9e0, data=0x5555567c73a0) at /home/elmarco/src/qemu/monitor.c:401
#8 0x00005555557882d2 in monitor_qapi_event_emit (event=QAPI_EVENT_SPICE_DISCONNECTED, qdict=0x5555567c73a0) at /home/elmarco/src/qemu/monitor.c:472
#9 0x000055555578838f in monitor_qapi_event_queue (event=QAPI_EVENT_SPICE_DISCONNECTED, qdict=0x5555567c73a0, errp=0x7fffffffca88) at /home/elmarco/src/qemu/monitor.c:497
#10 0x0000555555c15541 in qapi_event_send_spice_disconnected (server=0x5555571139d0, client=0x5555570d0db0, errp=0x5555566c0428 <error_abort>) at qapi-event.c:1038
#11 0x0000555555b11bc6 in channel_event (event=3, info=0x5555570d6c00) at ui/spice-core.c:248
#12 0x00007fffdcc9983a in adapter_channel_event (event=3, info=0x5555570d6c00) at reds.c:120
#13 0x00007fffdcc99a25 in reds_handle_channel_event (reds=0x5555567a9d60, event=3, info=0x5555570d6c00) at reds.c:324
#14 0x00007fffdcc7d4c4 in main_dispatcher_self_handle_channel_event (self=0x5555567b28b0, event=3, info=0x5555570d6c00) at main-dispatcher.c:175
#15 0x00007fffdcc7d5b1 in main_dispatcher_channel_event (self=0x5555567b28b0, event=3, info=0x5555570d6c00) at main-dispatcher.c:194
#16 0x00007fffdcca7674 in reds_stream_push_channel_event (s=0x5555570d9910, event=3) at reds-stream.c:354
#17 0x00007fffdcca749b in reds_stream_free (s=0x5555570d9910) at reds-stream.c:323
#18 0x00007fffdccb5dad in snd_disconnect_channel (channel=0x5555576a89a0) at sound.c:229
#19 0x00007fffdccb9e57 in snd_detach_common (worker=0x555557739720) at sound.c:1589
#20 0x00007fffdccb9f0e in snd_detach_playback (sin=0x5555569fe3f8) at sound.c:1602
#21 0x00007fffdcca3373 in spice_server_remove_interface (sin=0x5555569fe3f8) at reds.c:3387
#22 0x00005555558ff6e2 in line_out_fini (hw=0x5555569fe370) at audio/spiceaudio.c:152
#23 0x00005555558f909e in audio_atexit () at audio/audio.c:1754
#24 0x00007fffdb1941e8 in __run_exit_handlers (status=0, listp=0x7fffdb5175d8 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true) at exit.c:82
#25 0x00007fffdb194235 in __GI_exit (status=<optimized out>) at exit.c:104
#26 0x00007fffdb17b738 in __libc_start_main (main=0x5555558d7874 <main>, argc=67, argv=0x7fffffffcf48, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffcf38) at ../csu/libc-start.c:323
Add a monitor_cleanup() functions to remove all the monitors before
cleaning up the chardev. Note that we are "losing" some events that
used to be sent during atexit().
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20160801112343.29082-2-marcandre.lureau@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-08-01 14:23:42 +03:00
|
|
|
monitor_cleanup();
|
char: do not use atexit cleanup handler
It turns out qemu is calling exit() in various places from various
threads without taking much care of resources state. The atexit()
cleanup handlers cannot easily destroy resources that are in use (by
the same thread or other).
Since c1111a24a3, TCG arm guests run into the following abort() when
running tests, the chardev mutex is locked during the write, so
qemu_mutex_destroy() returns an error:
#0 0x00007fffdbb806f5 in raise () at /lib64/libc.so.6
#1 0x00007fffdbb822fa in abort () at /lib64/libc.so.6
#2 0x00005555557616fe in error_exit (err=<optimized out>, msg=msg@entry=0x555555c38c30 <__func__.14622> "qemu_mutex_destroy")
at /home/drjones/code/qemu/util/qemu-thread-posix.c:39
#3 0x0000555555b0be20 in qemu_mutex_destroy (mutex=mutex@entry=0x5555566aa0e0) at /home/drjones/code/qemu/util/qemu-thread-posix.c:57
#4 0x00005555558aab00 in qemu_chr_free_common (chr=0x5555566aa0e0) at /home/drjones/code/qemu/qemu-char.c:4029
#5 0x00005555558b05f9 in qemu_chr_delete (chr=<optimized out>) at /home/drjones/code/qemu/qemu-char.c:4038
#6 0x00005555558b05f9 in qemu_chr_delete (chr=<optimized out>) at /home/drjones/code/qemu/qemu-char.c:4044
#7 0x00005555558b062c in qemu_chr_cleanup () at /home/drjones/code/qemu/qemu-char.c:4557
#8 0x00007fffdbb851e8 in __run_exit_handlers () at /lib64/libc.so.6
#9 0x00007fffdbb85235 in () at /lib64/libc.so.6
#10 0x00005555558d1b39 in testdev_write (testdev=0x5555566aa0a0) at /home/drjones/code/qemu/backends/testdev.c:71
#11 0x00005555558d1b39 in testdev_write (chr=<optimized out>, buf=0x7fffc343fd9a "", len=0) at /home/drjones/code/qemu/backends/testdev.c:95
#12 0x00005555558adced in qemu_chr_fe_write (s=0x5555566aa0e0, buf=buf@entry=0x7fffc343fd98 "0q", len=len@entry=2) at /home/drjones/code/qemu/qemu-char.c:282
Instead of using a atexit() handler, only run the chardev cleanup as
initially proposed at the end of main(), where there are less chances
(hic) of conflicts or other races.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reported-by: Andrew Jones <drjones@redhat.com>
Message-Id: <20160704153823.16879-1-marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-07-04 18:38:23 +03:00
|
|
|
qemu_chr_cleanup();
|
2017-08-24 22:23:13 +03:00
|
|
|
user_creatable_cleanup();
|
2017-02-10 13:27:28 +03:00
|
|
|
/* TODO: unref root container, check all devices are ok */
|
2003-06-24 17:42:40 +04:00
|
|
|
}
|