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"
|
2022-04-20 16:25:49 +03:00
|
|
|
#include "qemu/help-texts.h"
|
2020-10-28 14:36:57 +03:00
|
|
|
#include "qemu/datadir.h"
|
2018-06-25 15:42:35 +03:00
|
|
|
#include "qemu/units.h"
|
2020-10-28 15:04:08 +03:00
|
|
|
#include "exec/cpu-common.h"
|
2022-03-23 18:57:34 +03:00
|
|
|
#include "exec/page-vary.h"
|
2019-08-12 08:23:51 +03:00
|
|
|
#include "hw/qdev-properties.h"
|
2021-03-18 18:55:10 +03:00
|
|
|
#include "qapi/compat-policy.h"
|
2018-02-01 14:18:31 +03:00
|
|
|
#include "qapi/error.h"
|
2020-12-11 19:52:41 +03:00
|
|
|
#include "qapi/qmp/qdict.h"
|
2021-07-29 17:03:43 +03:00
|
|
|
#include "qapi/qmp/qstring.h"
|
2021-03-12 20:35:47 +03:00
|
|
|
#include "qapi/qmp/qjson.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"
|
2022-02-08 23:08:56 +03:00
|
|
|
#include "qemu/hw-version.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"
|
2020-12-11 19:52:43 +03:00
|
|
|
#include "sysemu/runstate-action.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"
|
2020-05-08 13:02:22 +03:00
|
|
|
#include "sysemu/xen.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"
|
2021-02-04 19:39:24 +03:00
|
|
|
#include "qemu/accel.h"
|
2023-09-01 13:12:58 +03:00
|
|
|
#include "qemu/async-teardown.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"
|
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"
|
2020-02-19 19:08:37 +03:00
|
|
|
#include "sysemu/hostmem.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"
|
2020-10-28 15:04:08 +03:00
|
|
|
#include "hw/i386/x86.h"
|
|
|
|
#include "hw/i386/pc.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"
|
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"
|
2020-08-19 14:17:19 +03:00
|
|
|
#include "sysemu/cpu-timers.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"
|
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"
|
|
|
|
#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"
|
2023-01-12 18:20:13 +03:00
|
|
|
#ifdef CONFIG_TCG
|
2024-01-25 08:46:30 +03:00
|
|
|
#include "tcg/perf.h"
|
2023-01-12 18:20:13 +03:00
|
|
|
#endif
|
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
|
|
|
|
2020-08-05 16:02:20 +03:00
|
|
|
#include "trace.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"
|
2020-10-20 09:01:19 +03:00
|
|
|
#include "exec/confidential-guest-support.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"
|
2021-03-05 16:54:49 +03:00
|
|
|
#include "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"
|
2022-04-27 13:27:46 +03:00
|
|
|
#include "qapi/qapi-types-audio.h"
|
|
|
|
#include "qapi/qapi-visit-audio.h"
|
2018-02-11 12:36:01 +03:00
|
|
|
#include "qapi/qapi-visit-block-core.h"
|
2021-03-18 18:55:10 +03:00
|
|
|
#include "qapi/qapi-visit-compat.h"
|
hw/cxl/host: Add support for CXL Fixed Memory Windows.
The concept of these is introduced in [1] in terms of the
description the CEDT ACPI table. The principal is more general.
Unlike once traffic hits the CXL root bridges, the host system
memory address routing is implementation defined and effectively
static once observable by standard / generic system software.
Each CXL Fixed Memory Windows (CFMW) is a region of PA space
which has fixed system dependent routing configured so that
accesses can be routed to the CXL devices below a set of target
root bridges. The accesses may be interleaved across multiple
root bridges.
For QEMU we could have fully specified these regions in terms
of a base PA + size, but as the absolute address does not matter
it is simpler to let individual platforms place the memory regions.
ExampleS:
-cxl-fixed-memory-window targets.0=cxl.0,size=128G
-cxl-fixed-memory-window targets.0=cxl.1,size=128G
-cxl-fixed-memory-window targets.0=cxl0,targets.1=cxl.1,size=256G,interleave-granularity=2k
Specifies
* 2x 128G regions not interleaved across root bridges, one for each of
the root bridges with ids cxl.0 and cxl.1
* 256G region interleaved across root bridges with ids cxl.0 and cxl.1
with a 2k interleave granularity.
When system software enumerates the devices below a given root bridge
it can then decide which CFMW to use. If non interleave is desired
(or possible) it can use the appropriate CFMW for the root bridge in
question. If there are suitable devices to interleave across the
two root bridges then it may use the 3rd CFMS.
A number of other designs were considered but the following constraints
made it hard to adapt existing QEMU approaches to this particular problem.
1) The size must be known before a specific architecture / board brings
up it's PA memory map. We need to set up an appropriate region.
2) Using links to the host bridges provides a clean command line interface
but these links cannot be established until command line devices have
been added.
Hence the two step process used here of first establishing the size,
interleave-ways and granularity + caching the ids of the host bridges
and then, once available finding the actual host bridges so they can
be used later to support interleave decoding.
[1] CXL 2.0 ECN: CEDT CFMWS & QTG DSM (computeexpresslink.org / specifications)
Signed-off-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Acked-by: Markus Armbruster <armbru@redhat.com> # QAPI Schema
Message-Id: <20220429144110.25167-28-Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2022-04-29 17:40:52 +03:00
|
|
|
#include "qapi/qapi-visit-machine.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"
|
2020-10-27 11:22:57 +03:00
|
|
|
#include "qapi/qapi-commands-migration.h"
|
2020-10-27 15:42:04 +03:00
|
|
|
#include "qapi/qapi-commands-misc.h"
|
2021-03-12 20:35:46 +03:00
|
|
|
#include "qapi/qapi-visit-qom.h"
|
2018-11-22 10:16:13 +03:00
|
|
|
#include "qapi/qapi-commands-ui.h"
|
2022-04-20 16:26:07 +03:00
|
|
|
#include "block/qdict.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"
|
2022-04-20 16:26:06 +03:00
|
|
|
#include "qemu/keyval.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
|
|
|
|
|
2020-10-21 17:41:18 +03:00
|
|
|
typedef struct BlockdevOptionsQueueEntry {
|
|
|
|
BlockdevOptions *bdo;
|
|
|
|
Location loc;
|
|
|
|
QSIMPLEQ_ENTRY(BlockdevOptionsQueueEntry) entry;
|
|
|
|
} BlockdevOptionsQueueEntry;
|
|
|
|
|
|
|
|
typedef QSIMPLEQ_HEAD(, BlockdevOptionsQueueEntry) BlockdevOptionsQueue;
|
|
|
|
|
2021-03-12 20:35:46 +03:00
|
|
|
typedef struct ObjectOption {
|
|
|
|
ObjectOptions *opts;
|
|
|
|
QTAILQ_ENTRY(ObjectOption) next;
|
|
|
|
} ObjectOption;
|
|
|
|
|
2021-10-08 16:34:42 +03:00
|
|
|
typedef struct DeviceOption {
|
|
|
|
QDict *opts;
|
|
|
|
Location loc;
|
|
|
|
QTAILQ_ENTRY(DeviceOption) next;
|
|
|
|
} DeviceOption;
|
|
|
|
|
2020-10-21 12:17:39 +03:00
|
|
|
static const char *cpu_option;
|
2020-10-23 15:04:29 +03:00
|
|
|
static const char *mem_path;
|
2020-11-03 11:45:26 +03:00
|
|
|
static const char *incoming;
|
2020-10-21 17:19:08 +03:00
|
|
|
static const char *loadvm;
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
static const char *accelerators;
|
2022-04-14 19:52:58 +03:00
|
|
|
static bool have_custom_ram_size;
|
2022-04-14 19:52:59 +03:00
|
|
|
static const char *ram_memdev_id;
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
static QDict *machine_opts_dict;
|
2021-03-12 20:35:46 +03:00
|
|
|
static QTAILQ_HEAD(, ObjectOption) object_opts = QTAILQ_HEAD_INITIALIZER(object_opts);
|
2021-10-08 16:34:42 +03:00
|
|
|
static QTAILQ_HEAD(, DeviceOption) device_opts = QTAILQ_HEAD_INITIALIZER(device_opts);
|
2020-10-21 13:22:39 +03:00
|
|
|
static int display_remote;
|
2020-10-21 17:41:18 +03:00
|
|
|
static int snapshot;
|
2020-10-27 11:07:30 +03:00
|
|
|
static bool preconfig_requested;
|
2020-10-21 17:25:06 +03:00
|
|
|
static QemuPluginList plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list);
|
2020-10-21 17:41:18 +03:00
|
|
|
static BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
|
2020-10-21 13:22:39 +03:00
|
|
|
static bool nographic = false;
|
2020-10-21 17:21:22 +03:00
|
|
|
static int mem_prealloc; /* force preallocation of physical target memory */
|
2020-10-21 13:22:39 +03:00
|
|
|
static const char *vga_model = NULL;
|
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;
|
2020-10-21 12:17:39 +03:00
|
|
|
static const char *log_mask;
|
|
|
|
static const char *log_file;
|
|
|
|
static bool list_data_dirs;
|
2020-07-10 11:50:20 +03:00
|
|
|
static const char *qtest_chrdev;
|
|
|
|
static const char *qtest_log;
|
2010-12-08 14:35:05 +03:00
|
|
|
|
2014-03-10 18:37:40 +04:00
|
|
|
static int has_defaults = 1;
|
2023-10-05 12:55:03 +03:00
|
|
|
static int default_audio = 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
|
|
|
|
2023-10-30 13:15:29 +03:00
|
|
|
static const struct {
|
2009-12-08 15:11:41 +03:00
|
|
|
const char *driver;
|
|
|
|
int *flag;
|
|
|
|
} default_list[] = {
|
2023-11-09 14:23:54 +03:00
|
|
|
{ .driver = "xen-console", .flag = &default_serial },
|
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 },
|
|
|
|
{ .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 },
|
2021-07-01 09:24:21 +03:00
|
|
|
{ .driver = "virtio-vga-gl", .flag = &default_vga },
|
2023-03-22 02:13:29 +03:00
|
|
|
{ .driver = "virtio-vga-rutabaga", .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 */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
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 */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
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,
|
|
|
|
},
|
2020-06-26 23:19:00 +03:00
|
|
|
{
|
|
|
|
.name = "guest-name",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
.help = "Prepends guest name for error messages but only if "
|
|
|
|
"-name guest is set otherwise option is ignored\n",
|
|
|
|
},
|
2013-07-04 07:02:46 +04:00
|
|
|
{ /* 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",
|
2020-05-19 20:20:43 +03:00
|
|
|
}, {
|
|
|
|
.name = "gen_id",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
.help = "Sets id of the object generating the fw_cfg blob "
|
|
|
|
"to be inserted",
|
2015-04-29 18:21:53 +03:00
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2020-12-11 19:52:41 +03:00
|
|
|
static QemuOptsList qemu_action_opts = {
|
|
|
|
.name = "action",
|
|
|
|
.merge_lists = true,
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_action_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "shutdown",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},{
|
|
|
|
.name = "reboot",
|
|
|
|
.type = QEMU_OPT_STRING,
|
2020-12-12 01:31:52 +03:00
|
|
|
},{
|
|
|
|
.name = "panic",
|
|
|
|
.type = QEMU_OPT_STRING,
|
2020-12-11 19:52:41 +03:00
|
|
|
},{
|
|
|
|
.name = "watchdog",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2012-08-06 12:24:55 +04:00
|
|
|
const char *qemu_get_vm_name(void)
|
|
|
|
{
|
|
|
|
return qemu_name;
|
|
|
|
}
|
|
|
|
|
2021-10-08 16:34:42 +03:00
|
|
|
static void default_driver_disable(const char *driver)
|
2009-12-08 15:11:41 +03:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2021-10-08 16:34:42 +03:00
|
|
|
if (!driver) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-12-08 15:11:41 +03:00
|
|
|
for (i = 0; i < ARRAY_SIZE(default_list); i++) {
|
|
|
|
if (strcmp(default_list[i].driver, driver) != 0)
|
|
|
|
continue;
|
|
|
|
*(default_list[i].flag) = 0;
|
|
|
|
}
|
2021-10-08 16:34:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp)
|
|
|
|
{
|
|
|
|
const char *driver = qemu_opt_get(opts, "driver");
|
|
|
|
|
|
|
|
default_driver_disable(driver);
|
2009-12-08 15:11:41 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-08 16:34:42 +03:00
|
|
|
static void default_driver_check_json(void)
|
|
|
|
{
|
|
|
|
DeviceOption *opt;
|
|
|
|
|
|
|
|
QTAILQ_FOREACH(opt, &device_opts, next) {
|
|
|
|
const char *driver = qdict_get_try_str(opt->opts, "driver");
|
|
|
|
default_driver_disable(driver);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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 */
|
2022-11-04 19:06:59 +03:00
|
|
|
fdinfo = monitor_fdset_add_fd(dupfd, true, fdset_id, fd_opaque,
|
2015-03-15 12:16:28 +03:00
|
|
|
&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: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,
|
2023-10-16 21:39:06 +03:00
|
|
|
}, {
|
|
|
|
.name = "drawers",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
}, {
|
|
|
|
.name = "books",
|
|
|
|
.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 = "sockets",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
2019-06-20 08:45:25 +03:00
|
|
|
}, {
|
|
|
|
.name = "dies",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
hw/core/machine: Introduce CPU cluster topology support
The new Cluster-Aware Scheduling support has landed in Linux 5.16,
which has been proved to benefit the scheduling performance (e.g.
load balance and wake_affine strategy) on both x86_64 and AArch64.
So now in Linux 5.16 we have four-level arch-neutral CPU topology
definition like below and a new scheduler level for clusters.
struct cpu_topology {
int thread_id;
int core_id;
int cluster_id;
int package_id;
int llc_id;
cpumask_t thread_sibling;
cpumask_t core_sibling;
cpumask_t cluster_sibling;
cpumask_t llc_sibling;
}
A cluster generally means a group of CPU cores which share L2 cache
or other mid-level resources, and it is the shared resources that
is used to improve scheduler's behavior. From the point of view of
the size range, it's between CPU die and CPU core. For example, on
some ARM64 Kunpeng servers, we have 6 clusters in each NUMA node,
and 4 CPU cores in each cluster. The 4 CPU cores share a separate
L2 cache and a L3 cache tag, which brings cache affinity advantage.
In virtualization, on the Hosts which have pClusters (physical
clusters), if we can design a vCPU topology with cluster level for
guest kernel and have a dedicated vCPU pinning. A Cluster-Aware
Guest kernel can also make use of the cache affinity of CPU clusters
to gain similar scheduling performance.
This patch adds infrastructure for CPU cluster level topology
configuration and parsing, so that the user can specify cluster
parameter if their machines support it.
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
Message-Id: <20211228092221.21068-3-wangyanan55@huawei.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
[PMD: Added '(since 7.0)' to @clusters in qapi/machine.json]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2021-12-28 12:22:09 +03:00
|
|
|
}, {
|
|
|
|
.name = "clusters",
|
|
|
|
.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 */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2023-09-01 13:12:58 +03:00
|
|
|
#if defined(CONFIG_POSIX)
|
|
|
|
static QemuOptsList qemu_run_with_opts = {
|
|
|
|
.name = "run-with",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_run_with_opts.head),
|
|
|
|
.desc = {
|
|
|
|
#if defined(CONFIG_LINUX)
|
|
|
|
{
|
|
|
|
.name = "async-teardown",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
.name = "chroot",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
#define qemu_add_run_with_opts() qemu_add_opts(&qemu_run_with_opts)
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#define qemu_add_run_with_opts()
|
|
|
|
|
|
|
|
#endif /* CONFIG_POSIX */
|
|
|
|
|
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)
|
|
|
|
{
|
2021-01-25 14:35:06 +03:00
|
|
|
message_with_timestamp = qemu_opt_get_bool(opts, "timestamp", false);
|
2020-06-26 23:19:00 +03:00
|
|
|
error_with_guestname = qemu_opt_get_bool(opts, "guest-name", 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 */
|
|
|
|
|
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;
|
2020-02-07 19:19:48 +03:00
|
|
|
MachineClass *default_machineclass = NULL;
|
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) {
|
2020-02-07 19:19:48 +03:00
|
|
|
assert(default_machineclass == NULL && "Multiple default machines");
|
|
|
|
default_machineclass = mc;
|
2009-05-22 05:41:01 +04:00
|
|
|
}
|
|
|
|
}
|
2014-03-05 21:30:46 +04:00
|
|
|
|
2020-02-07 19:19:48 +03:00
|
|
|
return default_machineclass;
|
2009-05-22 05:41:01 +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",
|
2022-02-21 13:11:47 +03:00
|
|
|
g_get_prgname());
|
2011-12-19 10:19:31 +04:00
|
|
|
|
2021-05-17 14:34:21 +03:00
|
|
|
#define DEF(option, opt_arg, opt_enum, opt_help, arch_mask) \
|
|
|
|
if ((arch_mask) & arch_type) \
|
|
|
|
fputs(opt_help, stdout);
|
|
|
|
|
|
|
|
#define ARCHHEADING(text, arch_mask) \
|
|
|
|
if ((arch_mask) & arch_type) \
|
|
|
|
puts(stringify(text));
|
|
|
|
|
|
|
|
#define DEFHEADING(text) ARCHHEADING(text, QEMU_ARCH_ALL)
|
|
|
|
|
|
|
|
#include "qemu-options.def"
|
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"
|
2024-02-21 22:52:10 +03:00
|
|
|
"ctrl-alt-g toggle mouse and keyboard grab\n"
|
2010-02-08 12:04:56 +03:00
|
|
|
"\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
|
|
|
}
|
|
|
|
|
2023-09-01 13:13:01 +03:00
|
|
|
enum {
|
|
|
|
|
|
|
|
#define DEF(option, opt_arg, opt_enum, opt_help, arch_mask) \
|
|
|
|
opt_enum,
|
|
|
|
#define DEFHEADING(text)
|
|
|
|
#define ARCHHEADING(text, arch_mask)
|
|
|
|
|
|
|
|
#include "qemu-options.def"
|
|
|
|
};
|
|
|
|
|
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 },
|
2021-05-17 14:34:21 +03:00
|
|
|
|
|
|
|
#define DEF(option, opt_arg, opt_enum, opt_help, arch_mask) \
|
|
|
|
{ option, opt_arg, opt_enum, arch_mask },
|
|
|
|
#define DEFHEADING(text)
|
|
|
|
#define ARCHHEADING(text, arch_mask)
|
|
|
|
|
|
|
|
#include "qemu-options.def"
|
2022-12-20 13:02:54 +03:00
|
|
|
{ /* end of list */ }
|
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",
|
hw: Replace anti-social QOM type names
Several QOM type names contain ',':
ARM,bitband-memory
etraxfs,pic
etraxfs,serial
etraxfs,timer
fsl,imx25
fsl,imx31
fsl,imx6
fsl,imx6ul
fsl,imx7
grlib,ahbpnp
grlib,apbpnp
grlib,apbuart
grlib,gptimer
grlib,irqmp
qemu,register
SUNW,bpp
SUNW,CS4231
SUNW,DBRI
SUNW,DBRI.prom
SUNW,fdtwo
SUNW,sx
SUNW,tcx
xilinx,zynq_slcr
xlnx,zynqmp
xlnx,zynqmp-pmu-soc
xlnx,zynq-xadc
These are all device types. They can't be plugged with -device /
device_add, except for xlnx,zynqmp-pmu-soc, and I doubt that one
actually works.
They *can* be used with -device / device_add to request help.
Usability is poor, though: you have to double the comma, like this:
$ qemu-system-x86_64 -device SUNW,,fdtwo,help
Trap for the unwary. The fact that this was broken in
device-introspect-test for more than six years until commit e27bd49876
fixed it demonstrates that "the unwary" includes seasoned developers.
One QOM type name contains ' ': "ICH9 SMB". Because having to
remember just one way to quote would be too easy.
Rename the "SUNW,FOO types to "sun-FOO". Summarily replace ',' and '
' by '-' in the other type names.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20210304140229.575481-2-armbru@redhat.com>
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
2021-03-04 17:02:28 +03:00
|
|
|
.class_names = { "sun-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
|
|
|
},
|
2022-04-27 15:33:16 +03:00
|
|
|
#ifdef CONFIG_XEN_BACKEND
|
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
|
|
|
},
|
2022-04-27 15:33:16 +03:00
|
|
|
#endif
|
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] ||
|
2020-06-24 16:10:38 +03:00
|
|
|
module_object_class_by_name(ti->class_names[0]) ||
|
|
|
|
module_object_class_by_name(ti->class_names[1]);
|
2015-11-11 23:55:56 +03:00
|
|
|
}
|
|
|
|
|
2019-04-12 18:27:13 +03:00
|
|
|
static const char *
|
|
|
|
get_default_vga_model(const MachineClass *machine_class)
|
|
|
|
{
|
|
|
|
if (machine_class->default_display) {
|
2023-05-10 19:54:33 +03:00
|
|
|
for (int t = 0; t < VGA_TYPE_MAX; t++) {
|
|
|
|
const VGAInterfaceInfo *ti = &vga_interfaces[t];
|
|
|
|
|
|
|
|
if (ti->opt_name && vga_interface_available(t) &&
|
|
|
|
g_str_equal(ti->opt_name, machine_class->default_display)) {
|
|
|
|
return machine_class->default_display;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
warn_report_once("Default display '%s' is not available in this binary",
|
|
|
|
machine_class->default_display);
|
|
|
|
return NULL;
|
2019-04-12 18:27:13 +03:00
|
|
|
} 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 ?: "",
|
2022-05-03 12:17:24 +03:00
|
|
|
(def && g_str_equal(ti->opt_name, def)) ?
|
|
|
|
" (default)" : "");
|
2019-04-12 18:27:13 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2023-10-04 15:00:17 +03:00
|
|
|
static void parse_display_qapi(const char *str)
|
2018-05-07 12:55:36 +03:00
|
|
|
{
|
|
|
|
DisplayOptions *opts;
|
|
|
|
Visitor *v;
|
|
|
|
|
2023-10-04 15:00:17 +03:00
|
|
|
v = qobject_input_visitor_new_str(str, "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
|
|
|
{
|
2020-01-08 17:47:02 +03:00
|
|
|
if (is_help_option(p)) {
|
|
|
|
qemu_display_help();
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2023-10-25 16:05:08 +03:00
|
|
|
#ifdef CONFIG_VNC
|
|
|
|
const char *opts;
|
|
|
|
|
2022-05-19 18:56:24 +03:00
|
|
|
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 == '=') {
|
2021-01-20 17:42:35 +03:00
|
|
|
vnc_parse(opts + 1);
|
2023-11-17 14:15:13 +03:00
|
|
|
display_remote++;
|
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);
|
|
|
|
}
|
2023-10-25 16:05:08 +03:00
|
|
|
return;
|
2011-03-16 15:33:31 +03:00
|
|
|
}
|
2023-10-25 16:05:08 +03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
parse_display_qapi(p);
|
2011-03-16 15:33:31 +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;
|
2020-05-19 20:20:43 +03:00
|
|
|
const char *name, *file, *str, *gen_id;
|
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");
|
2020-05-19 20:20:43 +03:00
|
|
|
gen_id = qemu_opt_get(opts, "gen_id");
|
2015-09-29 19:29:01 +03:00
|
|
|
|
2020-05-19 20:20:43 +03:00
|
|
|
/* we need the name, and exactly one of: file, content string, gen_id */
|
|
|
|
if (!nonempty_str(name) ||
|
|
|
|
nonempty_str(file) + nonempty_str(str) + nonempty_str(gen_id) != 1) {
|
|
|
|
error_setg(errp, "name, plus exactly one of file,"
|
|
|
|
" string and gen_id, are needed");
|
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;
|
|
|
|
}
|
2020-05-19 20:17:09 +03:00
|
|
|
if (nonempty_str(gen_id)) {
|
|
|
|
/*
|
|
|
|
* In this particular case where the content is populated
|
|
|
|
* internally, the "etc/" namespace protection is relaxed,
|
|
|
|
* so do not emit a warning.
|
|
|
|
*/
|
|
|
|
} else if (strncmp(name, "opt/", 4) != 0) {
|
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);
|
2020-05-19 20:20:43 +03:00
|
|
|
} else if (nonempty_str(gen_id)) {
|
hw/nvram/fw_cfg: Let fw_cfg_add_from_generator() return boolean value
Commits b6d7e9b66f..a43770df5d simplified the error propagation.
Similarly to commit 6fd5bef10b "qom: Make functions taking Error**
return bool, not void", let fw_cfg_add_from_generator() return a
boolean value, not void.
This allow to simplify parse_fw_cfg() and fixes the error handling
issue reported by Coverity (CID 1430396):
In parse_fw_cfg():
Variable assigned once to a constant guards dead code.
Local variable local_err is assigned only once, to a constant
value, making it effectively constant throughout its scope.
If this is not the intent, examine the logic to see if there
is a missing assignment that would make local_err not remain
constant.
It's the call of fw_cfg_add_from_generator():
Error *local_err = NULL;
fw_cfg_add_from_generator(fw_cfg, name, gen_id, errp);
if (local_err) {
error_propagate(errp, local_err);
return -1;
}
return 0;
If it fails, parse_fw_cfg() sets an error and returns 0, which is
wrong. Harmless, because the only caller passes &error_fatal.
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Fixes: Coverity CID 1430396: 'Constant' variable guards dead code (DEADCODE)
Fixes: 6552d87c48 ("softmmu/vl: Let -fw_cfg option take a 'gen_id' argument")
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20200721131911.27380-3-philmd@redhat.com>
2020-07-20 15:20:15 +03:00
|
|
|
if (!fw_cfg_add_from_generator(fw_cfg, name, gen_id, errp)) {
|
2020-05-19 20:20:43 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
2015-09-29 19:29:01 +03:00
|
|
|
} 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
|
|
|
}
|
|
|
|
|
2023-10-04 15:00:17 +03:00
|
|
|
static void monitor_parse(const char *str, 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];
|
|
|
|
|
2023-10-04 15:00:17 +03:00
|
|
|
if (strstart(str, "chardev:", &p)) {
|
2009-12-08 15:11:50 +03:00
|
|
|
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);
|
2023-10-04 15:00:17 +03:00
|
|
|
opts = qemu_chr_parse_compat(label, str, true);
|
2009-12-08 15:11:50 +03:00
|
|
|
if (!opts) {
|
2023-10-04 15:00:17 +03:00
|
|
|
error_report("parse error: %s", str);
|
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;
|
|
|
|
}
|
|
|
|
|
2020-10-21 13:22:39 +03:00
|
|
|
static void qemu_disable_default_devices(void)
|
|
|
|
{
|
|
|
|
MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
|
|
|
|
|
2021-10-08 16:34:42 +03:00
|
|
|
default_driver_check_json();
|
2020-10-21 13:22:39 +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);
|
|
|
|
|
|
|
|
if (!vga_model && !default_vga) {
|
|
|
|
vga_interface_type = VGA_DEVICE;
|
2022-05-01 15:25:05 +03:00
|
|
|
vga_interface_created = true;
|
2020-10-21 13:22:39 +03:00
|
|
|
}
|
|
|
|
if (!has_defaults || machine_class->no_serial) {
|
|
|
|
default_serial = 0;
|
|
|
|
}
|
|
|
|
if (!has_defaults || machine_class->no_parallel) {
|
|
|
|
default_parallel = 0;
|
|
|
|
}
|
|
|
|
if (!has_defaults || machine_class->no_floppy) {
|
|
|
|
default_floppy = 0;
|
|
|
|
}
|
|
|
|
if (!has_defaults || machine_class->no_cdrom) {
|
|
|
|
default_cdrom = 0;
|
|
|
|
}
|
|
|
|
if (!has_defaults || machine_class->no_sdcard) {
|
|
|
|
default_sdcard = 0;
|
|
|
|
}
|
|
|
|
if (!has_defaults) {
|
2023-10-05 12:55:03 +03:00
|
|
|
default_audio = 0;
|
2020-10-21 13:22:39 +03:00
|
|
|
default_monitor = 0;
|
|
|
|
default_net = 0;
|
|
|
|
default_vga = 0;
|
2023-05-10 22:26:13 +03:00
|
|
|
} else {
|
|
|
|
if (default_net && machine_class->default_nic &&
|
|
|
|
!module_object_class_by_name(machine_class->default_nic)) {
|
|
|
|
warn_report("Default NIC '%s' is not available in this binary",
|
|
|
|
machine_class->default_nic);
|
|
|
|
default_net = 0;
|
|
|
|
}
|
2020-10-21 13:22:39 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-18 16:16:32 +03:00
|
|
|
static void qemu_setup_display(void)
|
|
|
|
{
|
|
|
|
if (dpy.type == DISPLAY_TYPE_DEFAULT && !display_remote) {
|
|
|
|
if (!qemu_display_find_default(&dpy)) {
|
|
|
|
dpy.type = DISPLAY_TYPE_NONE;
|
|
|
|
#if defined(CONFIG_VNC)
|
|
|
|
vnc_parse("localhost:0,to=99,id=default");
|
2023-11-17 14:15:13 +03:00
|
|
|
display_remote++;
|
2023-10-18 16:16:32 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (dpy.type == DISPLAY_TYPE_DEFAULT) {
|
|
|
|
dpy.type = DISPLAY_TYPE_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
qemu_display_early_init(&dpy);
|
|
|
|
}
|
|
|
|
|
2020-10-21 13:22:39 +03:00
|
|
|
static void qemu_create_default_devices(void)
|
|
|
|
{
|
|
|
|
MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
|
2023-09-05 22:18:08 +03:00
|
|
|
const char *vc = qemu_display_get_vc(&dpy);
|
2020-10-21 13:22:39 +03:00
|
|
|
|
|
|
|
if (is_daemonized()) {
|
|
|
|
/* According to documentation and historically, -nographic redirects
|
|
|
|
* serial port, parallel port and monitor to stdio, which does not work
|
|
|
|
* with -daemonize. We can redirect these to null instead, but since
|
|
|
|
* -nographic is legacy, let's just error out.
|
|
|
|
* We disallow -nographic only if all other ports are not redirected
|
|
|
|
* explicitly, to not break existing legacy setups which uses
|
|
|
|
* -nographic _and_ redirects all ports explicitly - this is valid
|
|
|
|
* usage, -nographic is just a no-op in this case.
|
|
|
|
*/
|
|
|
|
if (nographic
|
|
|
|
&& (default_parallel || default_serial || default_monitor)) {
|
|
|
|
error_report("-nographic cannot be used with -daemonize");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
vl: revert behaviour for -display none
Commit 1bec1cc0d ("ui/console: allow to override the default VC") changed
the behaviour of the "-display none" option, so that it now creates a
QEMU monitor on the terminal. "-display none" should not be tangled up
with whether we create a monitor or a serial terminal; it should purely
and only disable the graphical window. Changing its behaviour like this
breaks command lines which, for example, use semihosting for their
output and don't want a graphical window, as they now get a monitor they
never asked for.
It also breaks the command line we document for Xen in
docs/system/i386/xen.html:
$ ./qemu-system-x86_64 --accel kvm,xen-version=0x40011,kernel-irqchip=split \
-display none -chardev stdio,mux=on,id=char0,signal=off -mon char0 \
-device xen-console,chardev=char0 -drive file=${GUEST_IMAGE},if=xen
qemu-system-x86_64: cannot use stdio by multiple character devices
qemu-system-x86_64: could not connect serial device to character backend
'stdio'
When qemu is compiled without PIXMAN, by default the serials aren't
muxed with the monitor anymore on stdio. The serials are redirected to
"null" instead, and the monitor isn't set up.
Fixes: commit 1bec1cc0d ("ui/console: allow to override the default VC")
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
2023-11-17 17:03:16 +03:00
|
|
|
if (nographic) {
|
2023-09-05 22:18:08 +03:00
|
|
|
if (default_parallel) {
|
2020-10-21 13:22:39 +03:00
|
|
|
add_device_config(DEV_PARALLEL, "null");
|
2023-09-05 22:18:08 +03:00
|
|
|
}
|
2020-10-21 13:22:39 +03:00
|
|
|
if (default_serial && default_monitor) {
|
|
|
|
add_device_config(DEV_SERIAL, "mon:stdio");
|
|
|
|
} else {
|
2023-09-05 22:18:08 +03:00
|
|
|
if (default_serial) {
|
2020-10-21 13:22:39 +03:00
|
|
|
add_device_config(DEV_SERIAL, "stdio");
|
2023-09-05 22:18:08 +03:00
|
|
|
}
|
|
|
|
if (default_monitor) {
|
2020-10-21 13:22:39 +03:00
|
|
|
monitor_parse("stdio", "readline", false);
|
2023-09-05 22:18:08 +03:00
|
|
|
}
|
2020-10-21 13:22:39 +03:00
|
|
|
}
|
|
|
|
} else {
|
2023-09-05 22:18:08 +03:00
|
|
|
if (default_serial) {
|
|
|
|
add_device_config(DEV_SERIAL, vc ?: "null");
|
|
|
|
}
|
|
|
|
if (default_parallel) {
|
|
|
|
add_device_config(DEV_PARALLEL, vc ?: "null");
|
|
|
|
}
|
|
|
|
if (default_monitor && vc) {
|
|
|
|
monitor_parse(vc, "readline", false);
|
|
|
|
}
|
2020-10-21 13:22:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (default_net) {
|
|
|
|
QemuOptsList *net = qemu_find_opts("net");
|
|
|
|
qemu_opts_parse(net, "nic", true, &error_abort);
|
|
|
|
#ifdef CONFIG_SLIRP
|
|
|
|
qemu_opts_parse(net, "user", true, &error_abort);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If no default VGA is requested, the default is "none". */
|
|
|
|
if (default_vga) {
|
|
|
|
vga_model = get_default_vga_model(machine_class);
|
|
|
|
}
|
|
|
|
if (vga_model) {
|
|
|
|
select_vgahw(machine_class, vga_model);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2018-04-20 17:52:48 +03:00
|
|
|
serial_hds = g_renew(Chardev *, serial_hds, index + 1);
|
|
|
|
|
2024-01-22 19:36:06 +03:00
|
|
|
if (strcmp(devname, "none") == 0) {
|
|
|
|
/* Don't allocate a serial device for this index */
|
|
|
|
serial_hds[index] = NULL;
|
|
|
|
} else {
|
|
|
|
char label[32];
|
|
|
|
snprintf(label, sizeof(label), "serial%d", index);
|
|
|
|
|
|
|
|
serial_hds[index] = qemu_chr_new_mux_mon(label, devname, NULL);
|
|
|
|
if (!serial_hds[index]) {
|
|
|
|
error_report("could not connect serial device"
|
|
|
|
" to character backend '%s'", devname);
|
|
|
|
return -1;
|
|
|
|
}
|
2009-12-08 15:11:41 +03:00
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
|
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)));
|
|
|
|
}
|
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
static void machine_help_func(const QDict *qdict)
|
2011-07-23 14:38:37 +04:00
|
|
|
{
|
2023-07-22 09:26:40 +03:00
|
|
|
g_autoptr(GSList) machines = NULL;
|
|
|
|
GSList *el;
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
const char *type = qdict_get_try_str(qdict, "type");
|
2011-07-23 14:38:37 +04:00
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
machines = object_class_get_list(TYPE_MACHINE, false);
|
|
|
|
if (type) {
|
|
|
|
ObjectClass *machine_class = OBJECT_CLASS(find_machine(type, machines));
|
|
|
|
if (machine_class) {
|
|
|
|
type_print_class_properties(object_class_get_name(machine_class));
|
|
|
|
return;
|
2011-07-23 14:38:37 +04:00
|
|
|
}
|
|
|
|
}
|
2014-03-05 21:30:46 +04:00
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
printf("Supported machines are:\n");
|
|
|
|
machines = g_slist_sort(machines, machine_class_cmp);
|
|
|
|
for (el = machines; el; el = el->next) {
|
|
|
|
MachineClass *mc = el->data;
|
|
|
|
if (mc->alias) {
|
|
|
|
printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
|
|
|
|
}
|
|
|
|
printf("%-20s %s%s%s\n", mc->name, mc->desc,
|
|
|
|
mc->is_default ? " (default)" : "",
|
|
|
|
mc->deprecation_reason ? " (deprecated)" : "");
|
2019-04-05 09:41:21 +03:00
|
|
|
}
|
2011-07-23 14:38:37 +04:00
|
|
|
}
|
|
|
|
|
2021-07-29 16:53:27 +03:00
|
|
|
static void
|
|
|
|
machine_merge_property(const char *propname, QDict *prop, Error **errp)
|
|
|
|
{
|
|
|
|
QDict *opts;
|
|
|
|
|
|
|
|
opts = qdict_new();
|
|
|
|
/* Preserve the caller's reference to prop. */
|
|
|
|
qobject_ref(prop);
|
|
|
|
qdict_put(opts, propname, prop);
|
|
|
|
keyval_merge(machine_opts_dict, opts, errp);
|
|
|
|
qobject_unref(opts);
|
|
|
|
}
|
|
|
|
|
2021-05-13 16:03:48 +03:00
|
|
|
static void
|
|
|
|
machine_parse_property_opt(QemuOptsList *opts_list, const char *propname,
|
2021-07-20 15:54:07 +03:00
|
|
|
const char *arg)
|
2021-05-13 16:03:48 +03:00
|
|
|
{
|
2021-07-29 16:53:27 +03:00
|
|
|
QDict *prop = NULL;
|
2021-05-13 16:03:48 +03:00
|
|
|
bool help = false;
|
|
|
|
|
2021-07-20 15:54:07 +03:00
|
|
|
prop = keyval_parse(arg, opts_list->implied_opt_name, &help, &error_fatal);
|
2021-05-13 16:03:48 +03:00
|
|
|
if (help) {
|
|
|
|
qemu_opts_print_help(opts_list, true);
|
2021-07-20 15:54:08 +03:00
|
|
|
exit(0);
|
2021-05-13 16:03:48 +03:00
|
|
|
}
|
2021-07-20 15:54:07 +03:00
|
|
|
machine_merge_property(propname, prop, &error_fatal);
|
2021-07-29 16:53:27 +03:00
|
|
|
qobject_unref(prop);
|
2021-05-13 16:03:48 +03:00
|
|
|
}
|
|
|
|
|
2018-09-07 15:13:19 +03:00
|
|
|
static const char *pid_file;
|
2022-06-09 15:27:01 +03:00
|
|
|
struct UnlinkPidfileNotifier {
|
|
|
|
Notifier notifier;
|
|
|
|
char *pid_file_realpath;
|
|
|
|
};
|
|
|
|
static struct UnlinkPidfileNotifier qemu_unlink_pidfile_notifier;
|
2018-09-07 15:13:19 +03:00
|
|
|
|
|
|
|
static void qemu_unlink_pidfile(Notifier *n, void *data)
|
|
|
|
{
|
2022-06-09 15:27:01 +03:00
|
|
|
struct UnlinkPidfileNotifier *upn;
|
|
|
|
|
|
|
|
upn = DO_UPCAST(struct UnlinkPidfileNotifier, notifier, n);
|
|
|
|
unlink(upn->pid_file_realpath);
|
2018-09-07 15:13:19 +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;
|
|
|
|
}
|
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
static MachineClass *select_machine(QDict *qdict, Error **errp)
|
2016-02-12 22:02:24 +03:00
|
|
|
{
|
2023-10-04 15:00:17 +03:00
|
|
|
const char *machine_type = qdict_get_try_str(qdict, "type");
|
2019-04-05 09:41:19 +03:00
|
|
|
GSList *machines = object_class_get_list(TYPE_MACHINE, false);
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
MachineClass *machine_class;
|
|
|
|
Error *local_err = NULL;
|
2016-02-12 22:02:24 +03:00
|
|
|
|
2023-10-04 15:00:17 +03:00
|
|
|
if (machine_type) {
|
|
|
|
machine_class = find_machine(machine_type, machines);
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_del(qdict, "type");
|
|
|
|
if (!machine_class) {
|
|
|
|
error_setg(&local_err, "unsupported machine type");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
machine_class = find_default_machine(machines);
|
|
|
|
if (!machine_class) {
|
|
|
|
error_setg(&local_err, "No machine specified, and there is no default");
|
|
|
|
}
|
2016-02-12 22:02:24 +03:00
|
|
|
}
|
|
|
|
|
2019-04-05 09:41:19 +03:00
|
|
|
g_slist_free(machines);
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
if (local_err) {
|
|
|
|
error_append_hint(&local_err, "Use -machine help to list supported machines\n");
|
|
|
|
error_propagate(errp, local_err);
|
|
|
|
}
|
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
|
|
|
{
|
2019-11-13 13:44:48 +03:00
|
|
|
if (g_str_equal(name, skip)) {
|
2012-06-25 23:36:33 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
error: Eliminate error_propagate() with Coccinelle, part 1
When all we do with an Error we receive into a local variable is
propagating to somewhere else, we can just as well receive it there
right away. Convert
if (!foo(..., &err)) {
...
error_propagate(errp, err);
...
return ...
}
to
if (!foo(..., errp)) {
...
...
return ...
}
where nothing else needs @err. Coccinelle script:
@rule1 forall@
identifier fun, err, errp, lbl;
expression list args, args2;
binary operator op;
constant c1, c2;
symbol false;
@@
if (
(
- fun(args, &err, args2)
+ fun(args, errp, args2)
|
- !fun(args, &err, args2)
+ !fun(args, errp, args2)
|
- fun(args, &err, args2) op c1
+ fun(args, errp, args2) op c1
)
)
{
... when != err
when != lbl:
when strict
- error_propagate(errp, err);
... when != err
(
return;
|
return c2;
|
return false;
)
}
@rule2 forall@
identifier fun, err, errp, lbl;
expression list args, args2;
expression var;
binary operator op;
constant c1, c2;
symbol false;
@@
- var = fun(args, &err, args2);
+ var = fun(args, errp, args2);
... when != err
if (
(
var
|
!var
|
var op c1
)
)
{
... when != err
when != lbl:
when strict
- error_propagate(errp, err);
... when != err
(
return;
|
return c2;
|
return false;
|
return var;
)
}
@depends on rule1 || rule2@
identifier err;
@@
- Error *err = NULL;
... when != err
Not exactly elegant, I'm afraid.
The "when != lbl:" is necessary to avoid transforming
if (fun(args, &err)) {
goto out
}
...
out:
error_propagate(errp, err);
even though other paths to label out still need the error_propagate().
For an actual example, see sclp_realize().
Without the "when strict", Coccinelle transforms vfio_msix_setup(),
incorrectly. I don't know what exactly "when strict" does, only that
it helps here.
The match of return is narrower than what I want, but I can't figure
out how to express "return where the operand doesn't use @err". For
an example where it's too narrow, see vfio_intx_enable().
Silently fails to convert hw/arm/armsse.c, because Coccinelle gets
confused by ARMSSE being used both as typedef and function-like macro
there. Converted manually.
Line breaks tidied up manually. One nested declaration of @local_err
deleted manually. Preexisting unwanted blank line dropped in
hw/riscv/sifive_e.c.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20200707160613.848843-35-armbru@redhat.com>
2020-07-07 19:06:02 +03:00
|
|
|
if (!object_property_parse(obj, name, value, errp)) {
|
2012-06-25 23:36:33 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
/* *Non*recursively replace underscores with dashes in QDict keys. */
|
|
|
|
static void keyval_dashify(QDict *qdict, Error **errp)
|
2019-11-13 13:44:48 +03:00
|
|
|
{
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
const QDictEntry *ent, *next;
|
2019-11-13 13:44:48 +03:00
|
|
|
char *p;
|
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
for (ent = qdict_first(qdict); ent; ent = next) {
|
|
|
|
g_autofree char *new_key = NULL;
|
|
|
|
|
|
|
|
next = qdict_next(qdict, ent);
|
|
|
|
if (!strchr(ent->key, '_')) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
new_key = g_strdup(ent->key);
|
|
|
|
for (p = new_key; *p; p++) {
|
|
|
|
if (*p == '_') {
|
|
|
|
*p = '-';
|
|
|
|
}
|
2019-11-13 13:44:48 +03:00
|
|
|
}
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
if (qdict_haskey(qdict, new_key)) {
|
|
|
|
error_setg(errp, "Conflict between '%s' and '%s'", ent->key, new_key);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
qobject_ref(ent->value);
|
|
|
|
qdict_put_obj(qdict, new_key, ent->value);
|
|
|
|
qdict_del(qdict, ent->key);
|
2019-11-13 13:44:48 +03:00
|
|
|
}
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void qemu_apply_legacy_machine_options(QDict *qdict)
|
|
|
|
{
|
|
|
|
const char *value;
|
2022-04-14 19:52:58 +03:00
|
|
|
QObject *prop;
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
|
|
|
|
keyval_dashify(qdict, &error_fatal);
|
2019-11-13 13:44:48 +03:00
|
|
|
|
2019-11-13 12:10:47 +03:00
|
|
|
/* Legacy options do not correspond to MachineState properties. */
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
value = qdict_get_try_str(qdict, "accel");
|
|
|
|
if (value) {
|
|
|
|
accelerators = g_strdup(value);
|
|
|
|
qdict_del(qdict, "accel");
|
2019-11-13 12:10:47 +03:00
|
|
|
}
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
|
|
|
|
value = qdict_get_try_str(qdict, "igd-passthru");
|
|
|
|
if (value) {
|
|
|
|
object_register_sugar_prop(ACCEL_CLASS_NAME("xen"), "igd-passthru", value,
|
2020-08-14 10:24:50 +03:00
|
|
|
false);
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_del(qdict, "igd-passthru");
|
2019-11-13 12:56:53 +03:00
|
|
|
}
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
|
|
|
|
value = qdict_get_try_str(qdict, "kvm-shadow-mem");
|
|
|
|
if (value) {
|
|
|
|
object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), "kvm-shadow-mem", value,
|
2020-08-14 10:24:50 +03:00
|
|
|
false);
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_del(qdict, "kvm-shadow-mem");
|
2019-11-13 12:56:53 +03:00
|
|
|
}
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
|
|
|
|
value = qdict_get_try_str(qdict, "kernel-irqchip");
|
|
|
|
if (value) {
|
|
|
|
object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), "kernel-irqchip", value,
|
2020-08-14 10:24:50 +03:00
|
|
|
false);
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
object_register_sugar_prop(ACCEL_CLASS_NAME("whpx"), "kernel-irqchip", value,
|
2020-08-14 10:24:50 +03:00
|
|
|
false);
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_del(qdict, "kernel-irqchip");
|
2020-10-28 05:23:19 +03:00
|
|
|
}
|
2022-04-14 19:52:58 +03:00
|
|
|
|
2022-04-14 19:52:59 +03:00
|
|
|
value = qdict_get_try_str(qdict, "memory-backend");
|
|
|
|
if (value) {
|
|
|
|
if (mem_path) {
|
|
|
|
error_report("'-mem-path' can't be used together with"
|
|
|
|
"'-machine memory-backend'");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Resolved later. */
|
|
|
|
ram_memdev_id = g_strdup(value);
|
|
|
|
qdict_del(qdict, "memory-backend");
|
|
|
|
}
|
|
|
|
|
2022-04-14 19:52:58 +03:00
|
|
|
prop = qdict_get(qdict, "memory");
|
|
|
|
if (prop) {
|
|
|
|
have_custom_ram_size =
|
|
|
|
qobject_type(prop) == QTYPE_QDICT &&
|
|
|
|
qdict_haskey(qobject_to(QDict, prop), "size");
|
|
|
|
}
|
2019-11-13 13:44:48 +03:00
|
|
|
}
|
2015-05-13 19:14:04 +03:00
|
|
|
|
2021-03-12 20:35:46 +03:00
|
|
|
static void object_option_foreach_add(bool (*type_opt_predicate)(const char *))
|
|
|
|
{
|
|
|
|
ObjectOption *opt, *next;
|
|
|
|
|
|
|
|
QTAILQ_FOREACH_SAFE(opt, &object_opts, next, next) {
|
|
|
|
const char *type = ObjectType_str(opt->opts->qom_type);
|
|
|
|
if (type_opt_predicate(type)) {
|
|
|
|
user_creatable_add_qapi(opt->opts, &error_fatal);
|
|
|
|
qapi_free_ObjectOptions(opt->opts);
|
|
|
|
QTAILQ_REMOVE(&object_opts, opt, next);
|
|
|
|
g_free(opt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-24 13:57:52 +03:00
|
|
|
static void object_option_add_visitor(Visitor *v)
|
|
|
|
{
|
|
|
|
ObjectOption *opt = g_new0(ObjectOption, 1);
|
|
|
|
visit_type_ObjectOptions(v, NULL, &opt->opts, &error_fatal);
|
|
|
|
QTAILQ_INSERT_TAIL(&object_opts, opt, next);
|
|
|
|
}
|
|
|
|
|
2023-10-04 15:00:17 +03:00
|
|
|
static void object_option_parse(const char *str)
|
2021-03-12 20:35:46 +03:00
|
|
|
{
|
|
|
|
QemuOpts *opts;
|
|
|
|
const char *type;
|
|
|
|
Visitor *v;
|
|
|
|
|
2023-10-04 15:00:17 +03:00
|
|
|
if (str[0] == '{') {
|
|
|
|
QObject *obj = qobject_from_json(str, &error_fatal);
|
2021-03-12 20:35:46 +03:00
|
|
|
|
2021-03-12 20:35:47 +03:00
|
|
|
v = qobject_input_visitor_new(obj);
|
|
|
|
qobject_unref(obj);
|
|
|
|
} else {
|
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
|
2023-10-04 15:00:17 +03:00
|
|
|
str, true);
|
2021-03-12 20:35:47 +03:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
type = qemu_opt_get(opts, "qom-type");
|
|
|
|
if (!type) {
|
|
|
|
error_setg(&error_fatal, QERR_MISSING_PARAMETER, "qom-type");
|
|
|
|
}
|
|
|
|
if (user_creatable_print_help(type, opts)) {
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
v = opts_visitor_new(opts);
|
2021-03-12 20:35:46 +03:00
|
|
|
}
|
|
|
|
|
2021-05-24 13:57:52 +03:00
|
|
|
object_option_add_visitor(v);
|
2021-03-12 20:35:46 +03:00
|
|
|
visit_free(v);
|
|
|
|
}
|
|
|
|
|
vl: Allow ThreadContext objects to be created before the sandbox option
Currently, there is no way to configure a CPU affinity inside QEMU when
the sandbox option disables it for QEMU as a whole, for example, via:
-sandbox enable=on,resourcecontrol=deny
While ThreadContext objects can be created on the QEMU commandline and
the CPU affinity can be configured externally via the thread-id, this is
insufficient if a ThreadContext with a certain CPU affinity is already
required during QEMU startup, before we can intercept QEMU and
configure the CPU affinity.
Blocking sched_setaffinity() was introduced in 24f8cdc57224 ("seccomp:
add resourcecontrol argument to command line"), "to avoid any bigger of the
process". However, we only care about once QEMU is running, not when
the instance starting QEMU explicitly requests a certain CPU affinity
on the QEMU comandline.
Right now, for NUMA-aware preallocation of memory backends used for initial
machine RAM, one has to:
1) Start QEMU with the memory-backend with "prealloc=off"
2) Pause QEMU before it starts the guest (-S)
3) Create ThreadContext, configure the CPU affinity using the thread-id
4) Configure the ThreadContext as "prealloc-context" of the memory
backend
5) Trigger preallocation by setting "prealloc=on"
To simplify this handling especially for initial machine RAM,
allow creation of ThreadContext objects before parsing sandbox options,
such that the CPU affinity requested on the QEMU commandline alongside the
sandbox option can be set. As ThreadContext objects essentially only create
a persistent context thread and set the CPU affinity, this is easily
possible.
With this change, we can create a ThreadContext with a CPU affinity on
the QEMU commandline and use it for preallocation of memory backends
glued to the machine (simplified example):
To make "-name debug-threads=on" keep working as expected for the
context threads, perform earlier parsing of "-name".
qemu-system-x86_64 -m 1G \
-object thread-context,id=tc1,cpu-affinity=3-4 \
-object memory-backend-ram,id=pc.ram,size=1G,prealloc=on,prealloc-threads=2,prealloc-context=tc1 \
-machine memory-backend=pc.ram \
-S -monitor stdio -sandbox enable=on,resourcecontrol=deny
And while we can query the current CPU affinity:
(qemu) qom-get tc1 cpu-affinity
[
3,
4
]
We can no longer change it from QEMU directly:
(qemu) qom-set tc1 cpu-affinity 1-2
Error: Setting CPU affinity failed: Operation not permitted
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Message-Id: <20221014134720.168738-8-david@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
2022-10-14 16:47:20 +03:00
|
|
|
/*
|
|
|
|
* Very early object creation, before the sandbox options have been activated.
|
|
|
|
*/
|
|
|
|
static bool object_create_pre_sandbox(const char *type)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Objects should in general not get initialized "too early" without
|
|
|
|
* a reason. If you add one, state the reason in a comment!
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reason: -sandbox on,resourcecontrol=deny disallows setting CPU
|
|
|
|
* affinity of threads.
|
|
|
|
*/
|
|
|
|
if (g_str_equal(type, "thread-context")) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
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.
|
|
|
|
*/
|
2021-03-12 20:35:46 +03:00
|
|
|
static bool object_create_early(const char *type)
|
2015-05-13 19:14:04 +03:00
|
|
|
{
|
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!
|
|
|
|
*/
|
|
|
|
|
vl: Allow ThreadContext objects to be created before the sandbox option
Currently, there is no way to configure a CPU affinity inside QEMU when
the sandbox option disables it for QEMU as a whole, for example, via:
-sandbox enable=on,resourcecontrol=deny
While ThreadContext objects can be created on the QEMU commandline and
the CPU affinity can be configured externally via the thread-id, this is
insufficient if a ThreadContext with a certain CPU affinity is already
required during QEMU startup, before we can intercept QEMU and
configure the CPU affinity.
Blocking sched_setaffinity() was introduced in 24f8cdc57224 ("seccomp:
add resourcecontrol argument to command line"), "to avoid any bigger of the
process". However, we only care about once QEMU is running, not when
the instance starting QEMU explicitly requests a certain CPU affinity
on the QEMU comandline.
Right now, for NUMA-aware preallocation of memory backends used for initial
machine RAM, one has to:
1) Start QEMU with the memory-backend with "prealloc=off"
2) Pause QEMU before it starts the guest (-S)
3) Create ThreadContext, configure the CPU affinity using the thread-id
4) Configure the ThreadContext as "prealloc-context" of the memory
backend
5) Trigger preallocation by setting "prealloc=on"
To simplify this handling especially for initial machine RAM,
allow creation of ThreadContext objects before parsing sandbox options,
such that the CPU affinity requested on the QEMU commandline alongside the
sandbox option can be set. As ThreadContext objects essentially only create
a persistent context thread and set the CPU affinity, this is easily
possible.
With this change, we can create a ThreadContext with a CPU affinity on
the QEMU commandline and use it for preallocation of memory backends
glued to the machine (simplified example):
To make "-name debug-threads=on" keep working as expected for the
context threads, perform earlier parsing of "-name".
qemu-system-x86_64 -m 1G \
-object thread-context,id=tc1,cpu-affinity=3-4 \
-object memory-backend-ram,id=pc.ram,size=1G,prealloc=on,prealloc-threads=2,prealloc-context=tc1 \
-machine memory-backend=pc.ram \
-S -monitor stdio -sandbox enable=on,resourcecontrol=deny
And while we can query the current CPU affinity:
(qemu) qom-get tc1 cpu-affinity
[
3,
4
]
We can no longer change it from QEMU directly:
(qemu) qom-set tc1 cpu-affinity 1-2
Error: Setting CPU affinity failed: Operation not permitted
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Message-Id: <20221014134720.168738-8-david@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
2022-10-14 16:47:20 +03:00
|
|
|
/* Reason: already created. */
|
|
|
|
if (object_create_pre_sandbox(type)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-11-09 18:13:30 +03:00
|
|
|
/* Reason: property "chardev" */
|
|
|
|
if (g_str_equal(type, "rng-egd") ||
|
|
|
|
g_str_equal(type, "qtest")) {
|
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
|
|
|
|
|
2020-09-18 11:09:10 +03:00
|
|
|
/* Reason: vhost-user-blk-server property "node-name" */
|
|
|
|
if (g_str_equal(type, "vhost-user-blk-server")) {
|
|
|
|
return false;
|
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
|
2021-02-04 19:39:25 +03:00
|
|
|
/*
|
|
|
|
* Allocation of large amounts of memory may delay
|
2016-09-02 21:59:44 +03:00
|
|
|
* chardev initialization for too long, and trigger timeouts
|
|
|
|
* on software that waits for a monitor socket to be created
|
|
|
|
*/
|
|
|
|
if (g_str_has_prefix(type, "memory-backend-")) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-05-13 19:14:04 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
static void qemu_apply_machine_options(QDict *qdict)
|
2020-10-27 18:08:04 +03:00
|
|
|
{
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
object_set_properties_from_keyval(OBJECT(current_machine), qdict, false, &error_fatal);
|
2020-10-27 18:08:04 +03:00
|
|
|
|
2022-08-22 17:12:24 +03:00
|
|
|
if (semihosting_enabled(false) && !semihosting_get_argc()) {
|
2020-10-27 18:08:04 +03:00
|
|
|
/* fall back to the -kernel/-append */
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
semihosting_arg_fallback(current_machine->kernel_filename, current_machine->kernel_cmdline);
|
2020-10-27 18:08:04 +03:00
|
|
|
}
|
2021-05-13 16:03:48 +03:00
|
|
|
|
|
|
|
if (current_machine->smp.cpus > 1) {
|
2023-02-07 10:51:12 +03:00
|
|
|
replay_add_blocker("smp");
|
2021-05-13 16:03:48 +03:00
|
|
|
}
|
2020-10-27 18:08:04 +03:00
|
|
|
}
|
|
|
|
|
2020-10-21 17:41:18 +03:00
|
|
|
static void qemu_create_early_backends(void)
|
|
|
|
{
|
|
|
|
MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
|
ui: Make the DisplayType enum entries conditional
Libvirt's "domcapabilities" command has a way to state whether certain
graphic frontends are available in QEMU or not. Originally, libvirt
looked at the "--help" output of the QEMU binary to determine whether
SDL was available or not (by looking for the "-sdl" parameter in the
help text), but since libvirt stopped doing this analysis of the help
text, the detection of SDL is currently broken, see:
https://bugzilla.redhat.com/show_bug.cgi?id=1790902
QEMU should provide a way via the QMP interface instead. A simple way,
without introducing additional commands, is to make the DisplayType
enum entries conditional, so that the enum only contains the entries if
the corresponding CONFIG_xxx switches have been set. This of course
only gives an indication which possibilities have been enabled during
compile-time of QEMU (and does not take into account whether modules
are later available or not for example - for this we'd need a separate
command), but anyway, this should already be good enough for the above
bug ticket, and it's a good idea anyway to make the QMP interface
conditional here, so let's simply do it.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210615090439.70926-1-thuth@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2021-06-15 12:04:39 +03:00
|
|
|
#if defined(CONFIG_SDL)
|
|
|
|
const bool use_sdl = (dpy.type == DISPLAY_TYPE_SDL);
|
|
|
|
#else
|
|
|
|
const bool use_sdl = false;
|
|
|
|
#endif
|
|
|
|
#if defined(CONFIG_GTK)
|
|
|
|
const bool use_gtk = (dpy.type == DISPLAY_TYPE_GTK);
|
|
|
|
#else
|
|
|
|
const bool use_gtk = false;
|
|
|
|
#endif
|
2020-10-21 17:41:18 +03:00
|
|
|
|
ui: Make the DisplayType enum entries conditional
Libvirt's "domcapabilities" command has a way to state whether certain
graphic frontends are available in QEMU or not. Originally, libvirt
looked at the "--help" output of the QEMU binary to determine whether
SDL was available or not (by looking for the "-sdl" parameter in the
help text), but since libvirt stopped doing this analysis of the help
text, the detection of SDL is currently broken, see:
https://bugzilla.redhat.com/show_bug.cgi?id=1790902
QEMU should provide a way via the QMP interface instead. A simple way,
without introducing additional commands, is to make the DisplayType
enum entries conditional, so that the enum only contains the entries if
the corresponding CONFIG_xxx switches have been set. This of course
only gives an indication which possibilities have been enabled during
compile-time of QEMU (and does not take into account whether modules
are later available or not for example - for this we'd need a separate
command), but anyway, this should already be good enough for the above
bug ticket, and it's a good idea anyway to make the QMP interface
conditional here, so let's simply do it.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210615090439.70926-1-thuth@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2021-06-15 12:04:39 +03:00
|
|
|
if (dpy.has_window_close && !use_gtk && !use_sdl) {
|
2021-12-15 11:24:17 +03:00
|
|
|
error_report("window-close is only valid for GTK and SDL, "
|
2020-10-21 17:41:18 +03:00
|
|
|
"ignoring option");
|
|
|
|
}
|
|
|
|
|
|
|
|
qemu_console_early_init();
|
|
|
|
|
|
|
|
if (dpy.has_gl && dpy.gl != DISPLAYGL_MODE_OFF && display_opengl == 0) {
|
|
|
|
#if defined(CONFIG_OPENGL)
|
|
|
|
error_report("OpenGL is not supported by the display");
|
|
|
|
#else
|
|
|
|
error_report("OpenGL support is disabled");
|
|
|
|
#endif
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2021-03-12 20:35:46 +03:00
|
|
|
object_option_foreach_add(object_create_early);
|
2020-10-21 17:41:18 +03:00
|
|
|
|
|
|
|
/* spice needs the timers to be initialized by this point */
|
2021-11-15 11:00:27 +03:00
|
|
|
/* spice must initialize before audio as it changes the default audiodev */
|
2020-10-21 17:41:18 +03:00
|
|
|
/* spice must initialize before chardevs (for spicevmc and spiceport) */
|
|
|
|
qemu_spice.init();
|
|
|
|
|
|
|
|
qemu_opts_foreach(qemu_find_opts("chardev"),
|
|
|
|
chardev_init_func, NULL, &error_fatal);
|
|
|
|
|
|
|
|
#ifdef CONFIG_VIRTFS
|
|
|
|
qemu_opts_foreach(qemu_find_opts("fsdev"),
|
|
|
|
fsdev_init_func, NULL, &error_fatal);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Note: we need to create audio and block backends before
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
* setting machine properties, so they can be referred to.
|
2020-10-21 17:41:18 +03:00
|
|
|
*/
|
|
|
|
configure_blockdev(&bdo_queue, machine_class, snapshot);
|
2023-10-02 17:27:57 +03:00
|
|
|
audio_init_audiodevs();
|
2023-10-05 12:55:03 +03:00
|
|
|
if (default_audio) {
|
|
|
|
audio_create_default_audiodevs();
|
|
|
|
}
|
2020-10-21 17:41:18 +03:00
|
|
|
}
|
|
|
|
|
2015-05-13 19:14:04 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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
|
|
|
*/
|
2021-03-12 20:35:46 +03:00
|
|
|
static bool object_create_late(const char *type)
|
2015-05-13 19:14:04 +03:00
|
|
|
{
|
vl: Allow ThreadContext objects to be created before the sandbox option
Currently, there is no way to configure a CPU affinity inside QEMU when
the sandbox option disables it for QEMU as a whole, for example, via:
-sandbox enable=on,resourcecontrol=deny
While ThreadContext objects can be created on the QEMU commandline and
the CPU affinity can be configured externally via the thread-id, this is
insufficient if a ThreadContext with a certain CPU affinity is already
required during QEMU startup, before we can intercept QEMU and
configure the CPU affinity.
Blocking sched_setaffinity() was introduced in 24f8cdc57224 ("seccomp:
add resourcecontrol argument to command line"), "to avoid any bigger of the
process". However, we only care about once QEMU is running, not when
the instance starting QEMU explicitly requests a certain CPU affinity
on the QEMU comandline.
Right now, for NUMA-aware preallocation of memory backends used for initial
machine RAM, one has to:
1) Start QEMU with the memory-backend with "prealloc=off"
2) Pause QEMU before it starts the guest (-S)
3) Create ThreadContext, configure the CPU affinity using the thread-id
4) Configure the ThreadContext as "prealloc-context" of the memory
backend
5) Trigger preallocation by setting "prealloc=on"
To simplify this handling especially for initial machine RAM,
allow creation of ThreadContext objects before parsing sandbox options,
such that the CPU affinity requested on the QEMU commandline alongside the
sandbox option can be set. As ThreadContext objects essentially only create
a persistent context thread and set the CPU affinity, this is easily
possible.
With this change, we can create a ThreadContext with a CPU affinity on
the QEMU commandline and use it for preallocation of memory backends
glued to the machine (simplified example):
To make "-name debug-threads=on" keep working as expected for the
context threads, perform earlier parsing of "-name".
qemu-system-x86_64 -m 1G \
-object thread-context,id=tc1,cpu-affinity=3-4 \
-object memory-backend-ram,id=pc.ram,size=1G,prealloc=on,prealloc-threads=2,prealloc-context=tc1 \
-machine memory-backend=pc.ram \
-S -monitor stdio -sandbox enable=on,resourcecontrol=deny
And while we can query the current CPU affinity:
(qemu) qom-get tc1 cpu-affinity
[
3,
4
]
We can no longer change it from QEMU directly:
(qemu) qom-set tc1 cpu-affinity 1-2
Error: Setting CPU affinity failed: Operation not permitted
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Message-Id: <20221014134720.168738-8-david@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
2022-10-14 16:47:20 +03:00
|
|
|
return !object_create_early(type) && !object_create_pre_sandbox(type);
|
2015-05-13 19:14:04 +03:00
|
|
|
}
|
|
|
|
|
2020-10-27 16:36:52 +03:00
|
|
|
static void qemu_create_late_backends(void)
|
|
|
|
{
|
|
|
|
if (qtest_chrdev) {
|
|
|
|
qtest_server_init(qtest_chrdev, qtest_log, &error_fatal);
|
|
|
|
}
|
|
|
|
|
2022-10-21 12:09:07 +03:00
|
|
|
net_init_clients();
|
2020-10-27 16:36:52 +03:00
|
|
|
|
2021-03-12 20:35:46 +03:00
|
|
|
object_option_foreach_add(object_create_late);
|
2020-10-27 16:36:52 +03:00
|
|
|
|
2024-01-31 19:53:27 +03:00
|
|
|
/*
|
|
|
|
* Wait for any outstanding memory prealloc from created memory
|
|
|
|
* backends to complete.
|
|
|
|
*/
|
|
|
|
if (!qemu_finish_async_prealloc_mem(&error_fatal)) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2020-10-27 16:36:52 +03:00
|
|
|
if (tpm_init() < 0) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
qemu_opts_foreach(qemu_find_opts("mon"),
|
|
|
|
mon_init_func, NULL, &error_fatal);
|
|
|
|
|
|
|
|
if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
|
|
|
|
exit(1);
|
|
|
|
if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
|
|
|
|
exit(1);
|
|
|
|
if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
|
|
|
|
exit(1);
|
|
|
|
|
|
|
|
/* now chardevs have been created we may have semihosting to connect */
|
2022-05-02 02:59:06 +03:00
|
|
|
qemu_semihosting_chardev_init();
|
2020-10-27 16:36:52 +03:00
|
|
|
}
|
2015-05-13 19:14:04 +03:00
|
|
|
|
2020-10-27 18:16:18 +03:00
|
|
|
static void qemu_resolve_machine_memdev(void)
|
|
|
|
{
|
2022-04-14 19:52:59 +03:00
|
|
|
if (ram_memdev_id) {
|
2020-10-27 18:16:18 +03:00
|
|
|
Object *backend;
|
|
|
|
ram_addr_t backend_size;
|
|
|
|
|
2022-04-14 19:52:59 +03:00
|
|
|
backend = object_resolve_path_type(ram_memdev_id,
|
2020-10-27 18:16:18 +03:00
|
|
|
TYPE_MEMORY_BACKEND, NULL);
|
|
|
|
if (!backend) {
|
2022-04-14 19:52:59 +03:00
|
|
|
error_report("Memory backend '%s' not found", ram_memdev_id);
|
2020-10-27 18:16:18 +03:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2022-04-14 19:53:00 +03:00
|
|
|
if (!have_custom_ram_size) {
|
|
|
|
backend_size = object_property_get_uint(backend, "size", &error_abort);
|
|
|
|
current_machine->ram_size = backend_size;
|
2020-10-27 18:16:18 +03:00
|
|
|
}
|
2022-04-14 19:52:59 +03:00
|
|
|
object_property_set_link(OBJECT(current_machine),
|
|
|
|
"memory-backend", backend, &error_fatal);
|
2020-10-27 18:16:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-05 13:01:51 +03:00
|
|
|
static void parse_memory_options(void)
|
2015-01-11 13:38:43 +03:00
|
|
|
{
|
2022-08-05 13:01:51 +03:00
|
|
|
QemuOpts *opts = qemu_find_opts_singleton("memory");
|
2022-04-14 19:52:58 +03:00
|
|
|
QDict *dict, *prop;
|
2015-01-11 13:38:43 +03:00
|
|
|
const char *mem_str;
|
2022-08-05 13:01:51 +03:00
|
|
|
Location loc;
|
2016-02-12 22:02:27 +03:00
|
|
|
|
2022-08-05 13:01:51 +03:00
|
|
|
loc_push_none(&loc);
|
|
|
|
qemu_opts_loc_restore(opts);
|
2022-04-14 19:52:58 +03:00
|
|
|
|
|
|
|
prop = qdict_new();
|
2015-01-11 13:38:43 +03:00
|
|
|
|
2022-04-14 19:52:58 +03:00
|
|
|
if (qemu_opt_get_size(opts, "size", 0) != 0) {
|
2015-01-11 13:38:43 +03:00
|
|
|
/* Fix up legacy suffix-less format */
|
vl: remove dead code in parse_memory_options()
mem_str will never be an empty string, because qemu_opt_get_size() fails
if it encounters one:
$ ./qemu-system-x86_64 -m size=
qemu-system-x86_64: -m size=: Parameter size expects a non-negative number below 2^64
Optional suffix k, M, G, T, P or E means kilo-, mega-, giga-, tera-, peta-
and exabytes, respectively.
Suggested-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-08-05 20:15:39 +03:00
|
|
|
mem_str = qemu_opt_get(opts, "size");
|
2015-01-11 13:38:43 +03:00
|
|
|
if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
|
2022-04-14 19:52:58 +03:00
|
|
|
g_autofree char *mib_str = g_strdup_printf("%sM", mem_str);
|
|
|
|
qdict_put_str(prop, "size", mib_str);
|
|
|
|
} else {
|
|
|
|
qdict_put_str(prop, "size", mem_str);
|
2015-01-11 13:38:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-23 19:51:26 +03:00
|
|
|
if (qemu_opt_get(opts, "maxmem")) {
|
2022-04-14 19:52:58 +03:00
|
|
|
qdict_put_str(prop, "max-size", qemu_opt_get(opts, "maxmem"));
|
|
|
|
}
|
|
|
|
if (qemu_opt_get(opts, "slots")) {
|
|
|
|
qdict_put_str(prop, "slots", qemu_opt_get(opts, "slots"));
|
2015-01-11 13:38:43 +03:00
|
|
|
}
|
2016-02-12 22:02:27 +03:00
|
|
|
|
2022-04-14 19:52:58 +03:00
|
|
|
dict = qdict_new();
|
|
|
|
qdict_put(dict, "memory", prop);
|
|
|
|
keyval_merge(machine_opts_dict, dict, &error_fatal);
|
|
|
|
qobject_unref(dict);
|
2022-08-05 13:01:51 +03:00
|
|
|
loc_pop(&loc);
|
2020-10-27 18:04:37 +03:00
|
|
|
}
|
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
static void qemu_create_machine(QDict *qdict)
|
2020-10-27 18:04:37 +03:00
|
|
|
{
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
MachineClass *machine_class = select_machine(qdict, &error_fatal);
|
2020-10-27 18:04:37 +03:00
|
|
|
object_set_machine_compat_props(machine_class->compat_props);
|
|
|
|
|
|
|
|
current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class)));
|
|
|
|
object_property_add_child(object_get_root(), "machine",
|
|
|
|
OBJECT(current_machine));
|
|
|
|
object_property_add_child(container_get(OBJECT(current_machine),
|
|
|
|
"/unattached"),
|
|
|
|
"sysbus", OBJECT(sysbus_get_default()));
|
|
|
|
|
|
|
|
if (machine_class->minimum_page_bits) {
|
|
|
|
if (!set_preferred_target_page_bits(machine_class->minimum_page_bits)) {
|
|
|
|
/* This would be a board error: specifying a minimum smaller than
|
|
|
|
* a target's compile-time fixed setting.
|
|
|
|
*/
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_exec_init_all();
|
|
|
|
|
|
|
|
if (machine_class->hw_version) {
|
|
|
|
qemu_set_hw_version(machine_class->hw_version);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the default machine options from the machine if it is not already
|
|
|
|
* specified either by the configuration file or by the command line.
|
|
|
|
*/
|
|
|
|
if (machine_class->default_machine_opts) {
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
QDict *default_opts =
|
|
|
|
keyval_parse(machine_class->default_machine_opts, NULL, NULL,
|
|
|
|
&error_abort);
|
2021-07-13 05:15:52 +03:00
|
|
|
qemu_apply_legacy_machine_options(default_opts);
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
object_set_properties_from_keyval(OBJECT(current_machine), default_opts,
|
|
|
|
false, &error_abort);
|
|
|
|
qobject_unref(default_opts);
|
2020-10-27 18:04:37 +03:00
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
|
2021-05-24 13:57:51 +03:00
|
|
|
/*
|
|
|
|
* Return whether configuration group @group is stored in QemuOpts, or
|
|
|
|
* recorded as one or more QDicts by qemu_record_config_group.
|
|
|
|
*/
|
|
|
|
static bool is_qemuopts_group(const char *group)
|
|
|
|
{
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
if (g_str_equal(group, "object") ||
|
2023-09-21 15:04:39 +03:00
|
|
|
g_str_equal(group, "audiodev") ||
|
2021-07-29 17:03:43 +03:00
|
|
|
g_str_equal(group, "machine") ||
|
2022-04-14 19:52:57 +03:00
|
|
|
g_str_equal(group, "smp-opts") ||
|
2022-08-05 13:01:51 +03:00
|
|
|
g_str_equal(group, "boot-opts")) {
|
2021-05-24 13:57:52 +03:00
|
|
|
return false;
|
|
|
|
}
|
2021-05-24 13:57:51 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qemu_record_config_group(const char *group, QDict *dict,
|
|
|
|
bool from_json, Error **errp)
|
|
|
|
{
|
2021-05-24 13:57:52 +03:00
|
|
|
if (g_str_equal(group, "object")) {
|
|
|
|
Visitor *v = qobject_input_visitor_new_keyval(QOBJECT(dict));
|
|
|
|
object_option_add_visitor(v);
|
|
|
|
visit_free(v);
|
2023-09-21 15:04:39 +03:00
|
|
|
|
|
|
|
} else if (g_str_equal(group, "audiodev")) {
|
|
|
|
Audiodev *dev = NULL;
|
|
|
|
Visitor *v = qobject_input_visitor_new_keyval(QOBJECT(dict));
|
|
|
|
if (visit_type_Audiodev(v, NULL, &dev, errp)) {
|
|
|
|
audio_define(dev);
|
|
|
|
}
|
|
|
|
visit_free(v);
|
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
} else if (g_str_equal(group, "machine")) {
|
|
|
|
/*
|
|
|
|
* Cannot merge string-valued and type-safe dictionaries, so JSON
|
|
|
|
* is not accepted yet for -M.
|
|
|
|
*/
|
|
|
|
assert(!from_json);
|
|
|
|
keyval_merge(machine_opts_dict, dict, errp);
|
2021-07-29 17:03:43 +03:00
|
|
|
} else if (g_str_equal(group, "smp-opts")) {
|
|
|
|
machine_merge_property("smp", dict, &error_fatal);
|
2022-04-14 19:52:57 +03:00
|
|
|
} else if (g_str_equal(group, "boot-opts")) {
|
|
|
|
machine_merge_property("boot", dict, &error_fatal);
|
2021-05-24 13:57:52 +03:00
|
|
|
} else {
|
|
|
|
abort();
|
|
|
|
}
|
2021-05-24 13:57:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse non-QemuOpts config file groups, pass the rest to
|
|
|
|
* qemu_config_do_parse.
|
|
|
|
*/
|
|
|
|
static void qemu_parse_config_group(const char *group, QDict *qdict,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
QObject *crumpled;
|
|
|
|
if (is_qemuopts_group(group)) {
|
|
|
|
qemu_config_do_parse(group, qdict, opaque, errp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
crumpled = qdict_crumple(qdict, errp);
|
|
|
|
if (!crumpled) {
|
|
|
|
return;
|
|
|
|
}
|
2021-07-05 20:17:38 +03:00
|
|
|
switch (qobject_type(crumpled)) {
|
|
|
|
case QTYPE_QDICT:
|
|
|
|
qemu_record_config_group(group, qobject_to(QDict, crumpled), false, errp);
|
|
|
|
break;
|
|
|
|
case QTYPE_QLIST:
|
2021-05-24 13:57:51 +03:00
|
|
|
error_setg(errp, "Lists cannot be at top level of a configuration section");
|
2021-07-05 20:17:38 +03:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
2021-05-24 13:57:51 +03:00
|
|
|
}
|
2021-07-05 20:17:38 +03:00
|
|
|
qobject_unref(crumpled);
|
2021-05-24 13:57:51 +03:00
|
|
|
}
|
|
|
|
|
2021-02-26 20:08:16 +03:00
|
|
|
static void qemu_read_default_config_file(Error **errp)
|
2017-01-17 21:00:51 +03:00
|
|
|
{
|
2021-02-26 20:08:16 +03:00
|
|
|
ERRP_GUARD();
|
2017-01-17 21:00:51 +03:00
|
|
|
int ret;
|
2020-08-18 12:59:50 +03:00
|
|
|
g_autofree char *file = get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf");
|
2017-01-17 21:00:51 +03:00
|
|
|
|
2021-05-24 13:57:51 +03:00
|
|
|
ret = qemu_read_config_file(file, qemu_parse_config_group, errp);
|
2021-02-26 20:08:16 +03:00
|
|
|
if (ret < 0) {
|
|
|
|
if (ret == -ENOENT) {
|
|
|
|
error_free(*errp);
|
|
|
|
*errp = NULL;
|
|
|
|
}
|
2017-01-17 21:00:51 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-24 13:57:51 +03:00
|
|
|
static void qemu_set_option(const char *str, Error **errp)
|
2020-11-12 16:16:22 +03:00
|
|
|
{
|
|
|
|
char group[64], id[64], arg[64];
|
|
|
|
QemuOptsList *list;
|
|
|
|
QemuOpts *opts;
|
|
|
|
int rc, offset;
|
|
|
|
|
|
|
|
rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset);
|
|
|
|
if (rc < 3 || str[offset] != '=') {
|
2021-05-24 13:57:51 +03:00
|
|
|
error_setg(errp, "can't parse: \"%s\"", str);
|
|
|
|
return;
|
2020-11-12 16:16:22 +03:00
|
|
|
}
|
|
|
|
|
2021-05-24 13:57:51 +03:00
|
|
|
if (!is_qemuopts_group(group)) {
|
|
|
|
error_setg(errp, "-set is not supported with %s", group);
|
|
|
|
} else {
|
|
|
|
list = qemu_find_opts_err(group, errp);
|
|
|
|
if (list) {
|
|
|
|
opts = qemu_opts_find(list, id);
|
|
|
|
if (!opts) {
|
|
|
|
error_setg(errp, "there is no %s \"%s\" defined", group, id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
qemu_opt_set(opts, arg, str + offset + 1, errp);
|
|
|
|
}
|
2020-11-12 16:16:22 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
{
|
2023-12-08 14:35:23 +03:00
|
|
|
return !icount_configure(opts, errp);
|
2019-11-13 14:37:00 +03:00
|
|
|
}
|
|
|
|
|
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;
|
2020-07-10 11:50:20 +03:00
|
|
|
bool qtest_with_kvm;
|
|
|
|
|
2023-01-13 13:35:40 +03:00
|
|
|
if (!acc) {
|
|
|
|
error_setg(errp, QERR_MISSING_PARAMETER, "accel");
|
|
|
|
goto bad;
|
|
|
|
}
|
|
|
|
|
2020-07-10 11:50:20 +03:00
|
|
|
qtest_with_kvm = g_str_equal(acc, "kvm") && qtest_chrdev != NULL;
|
2019-11-13 12:10:47 +03:00
|
|
|
|
|
|
|
if (!ac) {
|
2020-07-10 11:50:20 +03:00
|
|
|
if (!qtest_with_kvm) {
|
|
|
|
error_report("invalid accelerator %s", acc);
|
|
|
|
}
|
2023-01-13 13:35:40 +03:00
|
|
|
goto bad;
|
2019-11-13 12:10:47 +03:00
|
|
|
}
|
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);
|
2024-01-17 18:14:30 +03:00
|
|
|
|
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) {
|
2020-07-10 11:50:20 +03:00
|
|
|
if (!qtest_with_kvm || ret != -ENOENT) {
|
|
|
|
error_report("failed to initialize %s: %s", acc, strerror(-ret));
|
|
|
|
}
|
2023-01-13 13:35:40 +03:00
|
|
|
goto bad;
|
2019-11-13 12:10:47 +03:00
|
|
|
}
|
2019-11-13 17:16:44 +03:00
|
|
|
|
2019-11-13 12:10:47 +03:00
|
|
|
return 1;
|
2023-01-13 13:35:40 +03:00
|
|
|
|
|
|
|
bad:
|
|
|
|
*p_init_failed = true;
|
|
|
|
return 0;
|
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
|
|
|
bool init_failed = false;
|
|
|
|
|
|
|
|
qemu_opts_foreach(qemu_find_opts("icount"),
|
|
|
|
do_configure_icount, NULL, &error_fatal);
|
|
|
|
|
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;
|
|
|
|
|
2020-11-02 18:46:52 +03:00
|
|
|
if (accelerators == NULL) {
|
2019-11-13 12:10:47 +03:00
|
|
|
/* 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 */
|
2020-11-02 18:46:52 +03:00
|
|
|
accelerators = "kvm:tcg";
|
2019-11-13 12:10:47 +03:00
|
|
|
} else {
|
2020-11-02 18:46:52 +03:00
|
|
|
accelerators = "tcg:kvm";
|
2019-11-13 12:10:47 +03:00
|
|
|
}
|
2020-01-09 04:07:30 +03:00
|
|
|
} else if (have_kvm) {
|
2020-11-02 18:46:52 +03:00
|
|
|
accelerators = "kvm";
|
2020-01-09 04:07:30 +03:00
|
|
|
} else if (have_tcg) {
|
2020-11-02 18:46:52 +03:00
|
|
|
accelerators = "tcg";
|
2020-01-09 04:07:30 +03:00
|
|
|
} else {
|
|
|
|
error_report("No accelerator selected and"
|
|
|
|
" no default accelerator available");
|
|
|
|
exit(1);
|
2019-11-13 11:59:04 +03:00
|
|
|
}
|
|
|
|
}
|
2020-11-02 18:46:52 +03:00
|
|
|
accel_list = g_strsplit(accelerators, ":", 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 {
|
2020-11-02 18:46:52 +03:00
|
|
|
if (accelerators != NULL) {
|
2019-11-13 12:10:47 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2020-07-10 11:50:20 +03:00
|
|
|
if (init_failed && !qtest_chrdev) {
|
2022-06-24 17:42:56 +03:00
|
|
|
error_report("falling back to %s", current_accel_name());
|
2019-11-13 11:59:04 +03:00
|
|
|
}
|
|
|
|
|
2020-08-19 14:17:19 +03:00
|
|
|
if (icount_enabled() && !tcg_enabled()) {
|
2019-11-14 13:10:43 +03:00
|
|
|
error_report("-icount is not allowed with hardware virtualization");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
static void qemu_validate_options(const QDict *machine_opts)
|
2020-11-03 11:45:26 +03:00
|
|
|
{
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
const char *kernel_filename = qdict_get_try_str(machine_opts, "kernel");
|
|
|
|
const char *initrd_filename = qdict_get_try_str(machine_opts, "initrd");
|
|
|
|
const char *kernel_cmdline = qdict_get_try_str(machine_opts, "append");
|
2020-11-03 11:45:26 +03:00
|
|
|
|
|
|
|
if (kernel_filename == NULL) {
|
|
|
|
if (kernel_cmdline != NULL) {
|
|
|
|
error_report("-append only allowed with -kernel option");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (initrd_filename != NULL) {
|
|
|
|
error_report("-initrd only allowed with -kernel option");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-01 17:25:19 +03:00
|
|
|
if (loadvm && incoming) {
|
|
|
|
error_report("'incoming' and 'loadvm' options are mutually exclusive");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2020-10-27 11:07:30 +03:00
|
|
|
if (loadvm && preconfig_requested) {
|
2020-10-21 17:19:08 +03:00
|
|
|
error_report("'preconfig' and 'loadvm' options are "
|
|
|
|
"mutually exclusive");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2020-10-27 16:15:53 +03:00
|
|
|
if (incoming && preconfig_requested && strcmp(incoming, "defer") != 0) {
|
|
|
|
error_report("'preconfig' supports '-incoming defer' only");
|
2020-11-03 11:45:26 +03:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_CURSES
|
|
|
|
if (is_daemonized() && dpy.type == DISPLAY_TYPE_CURSES) {
|
|
|
|
error_report("curses display cannot be used with -daemonize");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-10-21 17:21:22 +03:00
|
|
|
static void qemu_process_sugar_options(void)
|
|
|
|
{
|
|
|
|
if (mem_prealloc) {
|
2021-07-29 17:03:43 +03:00
|
|
|
QObject *smp = qdict_get(machine_opts_dict, "smp");
|
|
|
|
if (smp && qobject_type(smp) == QTYPE_QDICT) {
|
|
|
|
QObject *cpus = qdict_get(qobject_to(QDict, smp), "cpus");
|
|
|
|
if (cpus && qobject_type(cpus) == QTYPE_QSTRING) {
|
|
|
|
const char *val = qstring_get_str(qobject_to(QString, cpus));
|
|
|
|
object_register_sugar_prop("memory-backend", "prealloc-threads",
|
|
|
|
val, false);
|
|
|
|
}
|
|
|
|
}
|
2020-08-14 10:24:50 +03:00
|
|
|
object_register_sugar_prop("memory-backend", "prealloc", "on", false);
|
2020-10-21 17:21:22 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-11 19:52:41 +03:00
|
|
|
/* -action processing */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Process all the -action parameters parsed from cmdline.
|
|
|
|
*/
|
|
|
|
static int process_runstate_actions(void *opaque, QemuOpts *opts, Error **errp)
|
|
|
|
{
|
|
|
|
Error *local_err = NULL;
|
|
|
|
QDict *qdict = qemu_opts_to_qdict(opts, NULL);
|
|
|
|
QObject *ret = NULL;
|
|
|
|
qmp_marshal_set_action(qdict, &ret, &local_err);
|
|
|
|
qobject_unref(ret);
|
|
|
|
qobject_unref(qdict);
|
|
|
|
if (local_err) {
|
|
|
|
error_propagate(errp, local_err);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-10-21 12:17:39 +03:00
|
|
|
static void qemu_process_early_options(void)
|
|
|
|
{
|
vl: Allow ThreadContext objects to be created before the sandbox option
Currently, there is no way to configure a CPU affinity inside QEMU when
the sandbox option disables it for QEMU as a whole, for example, via:
-sandbox enable=on,resourcecontrol=deny
While ThreadContext objects can be created on the QEMU commandline and
the CPU affinity can be configured externally via the thread-id, this is
insufficient if a ThreadContext with a certain CPU affinity is already
required during QEMU startup, before we can intercept QEMU and
configure the CPU affinity.
Blocking sched_setaffinity() was introduced in 24f8cdc57224 ("seccomp:
add resourcecontrol argument to command line"), "to avoid any bigger of the
process". However, we only care about once QEMU is running, not when
the instance starting QEMU explicitly requests a certain CPU affinity
on the QEMU comandline.
Right now, for NUMA-aware preallocation of memory backends used for initial
machine RAM, one has to:
1) Start QEMU with the memory-backend with "prealloc=off"
2) Pause QEMU before it starts the guest (-S)
3) Create ThreadContext, configure the CPU affinity using the thread-id
4) Configure the ThreadContext as "prealloc-context" of the memory
backend
5) Trigger preallocation by setting "prealloc=on"
To simplify this handling especially for initial machine RAM,
allow creation of ThreadContext objects before parsing sandbox options,
such that the CPU affinity requested on the QEMU commandline alongside the
sandbox option can be set. As ThreadContext objects essentially only create
a persistent context thread and set the CPU affinity, this is easily
possible.
With this change, we can create a ThreadContext with a CPU affinity on
the QEMU commandline and use it for preallocation of memory backends
glued to the machine (simplified example):
To make "-name debug-threads=on" keep working as expected for the
context threads, perform earlier parsing of "-name".
qemu-system-x86_64 -m 1G \
-object thread-context,id=tc1,cpu-affinity=3-4 \
-object memory-backend-ram,id=pc.ram,size=1G,prealloc=on,prealloc-threads=2,prealloc-context=tc1 \
-machine memory-backend=pc.ram \
-S -monitor stdio -sandbox enable=on,resourcecontrol=deny
And while we can query the current CPU affinity:
(qemu) qom-get tc1 cpu-affinity
[
3,
4
]
We can no longer change it from QEMU directly:
(qemu) qom-set tc1 cpu-affinity 1-2
Error: Setting CPU affinity failed: Operation not permitted
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Message-Id: <20221014134720.168738-8-david@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
2022-10-14 16:47:20 +03:00
|
|
|
qemu_opts_foreach(qemu_find_opts("name"),
|
|
|
|
parse_name, NULL, &error_fatal);
|
|
|
|
|
|
|
|
object_option_foreach_add(object_create_pre_sandbox);
|
|
|
|
|
2020-10-21 12:17:39 +03:00
|
|
|
#ifdef CONFIG_SECCOMP
|
|
|
|
QemuOptsList *olist = qemu_find_opts_err("sandbox", NULL);
|
|
|
|
if (olist) {
|
|
|
|
qemu_opts_foreach(olist, parse_sandbox, NULL, &error_fatal);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-12-11 19:52:41 +03:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("action"),
|
|
|
|
process_runstate_actions, NULL, &error_fatal)) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2020-10-21 12:17:39 +03:00
|
|
|
#ifndef _WIN32
|
|
|
|
qemu_opts_foreach(qemu_find_opts("add-fd"),
|
|
|
|
parse_add_fd, NULL, &error_fatal);
|
|
|
|
|
|
|
|
qemu_opts_foreach(qemu_find_opts("add-fd"),
|
|
|
|
cleanup_add_fd, NULL, &error_fatal);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Open the logfile at this point and set the log mask if necessary. */
|
2022-04-17 21:30:10 +03:00
|
|
|
{
|
|
|
|
int mask = 0;
|
|
|
|
if (log_mask) {
|
|
|
|
mask = qemu_str_to_log_mask(log_mask);
|
|
|
|
if (!mask) {
|
|
|
|
qemu_print_log_usage(stdout);
|
|
|
|
exit(1);
|
|
|
|
}
|
2020-10-21 12:17:39 +03:00
|
|
|
}
|
2022-04-17 21:30:10 +03:00
|
|
|
qemu_set_log_filename_flags(log_file, mask, &error_fatal);
|
2020-10-21 12:17:39 +03:00
|
|
|
}
|
|
|
|
|
2020-10-28 14:36:57 +03:00
|
|
|
qemu_add_default_firmwarepath();
|
2020-10-21 12:17:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void qemu_process_help_options(void)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Check for -cpu help and -device help before we call select_machine(),
|
|
|
|
* which will return an error if the architecture has no default machine
|
|
|
|
* type and the user did not specify one, so that the user doesn't need
|
|
|
|
* to say '-cpu help -machine something'.
|
|
|
|
*/
|
|
|
|
if (cpu_option && is_help_option(cpu_option)) {
|
2023-04-19 15:48:31 +03:00
|
|
|
list_cpus();
|
2020-10-21 12:17:39 +03:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qemu_opts_foreach(qemu_find_opts("device"),
|
|
|
|
device_help_func, NULL, NULL)) {
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* -L help lists the data directories and exits. */
|
|
|
|
if (list_data_dirs) {
|
2020-10-28 14:36:57 +03:00
|
|
|
qemu_list_data_dirs();
|
2020-10-21 12:17:39 +03:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qemu_maybe_daemonize(const char *pid_file)
|
|
|
|
{
|
2021-06-10 11:47:41 +03:00
|
|
|
Error *err = NULL;
|
2020-10-21 12:17:39 +03:00
|
|
|
|
|
|
|
os_daemonize();
|
|
|
|
rcu_disable_atfork();
|
|
|
|
|
2022-06-09 15:27:00 +03:00
|
|
|
if (pid_file) {
|
2022-06-09 15:27:01 +03:00
|
|
|
char *pid_file_realpath = NULL;
|
|
|
|
|
2022-06-09 15:27:00 +03:00
|
|
|
if (!qemu_write_pidfile(pid_file, &err)) {
|
|
|
|
error_reportf_err(err, "cannot create PID file: ");
|
|
|
|
exit(1);
|
|
|
|
}
|
2020-10-21 12:17:39 +03:00
|
|
|
|
2022-06-09 15:27:01 +03:00
|
|
|
pid_file_realpath = g_malloc0(PATH_MAX);
|
|
|
|
if (!realpath(pid_file, pid_file_realpath)) {
|
2022-10-31 12:47:16 +03:00
|
|
|
if (errno != ENOENT) {
|
|
|
|
warn_report("not removing PID file on exit: cannot resolve PID "
|
|
|
|
"file path: %s: %s", pid_file, strerror(errno));
|
|
|
|
}
|
|
|
|
return;
|
2022-06-09 15:27:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
qemu_unlink_pidfile_notifier = (struct UnlinkPidfileNotifier) {
|
|
|
|
.notifier = {
|
|
|
|
.notify = qemu_unlink_pidfile,
|
|
|
|
},
|
|
|
|
.pid_file_realpath = pid_file_realpath,
|
|
|
|
};
|
|
|
|
qemu_add_exit_notifier(&qemu_unlink_pidfile_notifier.notifier);
|
2022-06-09 15:27:00 +03:00
|
|
|
}
|
2020-10-21 12:17:39 +03:00
|
|
|
}
|
|
|
|
|
2020-10-27 11:07:30 +03:00
|
|
|
static void qemu_init_displays(void)
|
|
|
|
{
|
|
|
|
DisplayState *ds;
|
|
|
|
|
|
|
|
/* init local displays */
|
|
|
|
ds = init_displaystate();
|
|
|
|
qemu_display_init(ds, &dpy);
|
|
|
|
|
|
|
|
/* must be after terminal init, SDL library changes signal handlers */
|
|
|
|
os_setup_signal_handling();
|
|
|
|
|
|
|
|
/* init remote displays */
|
|
|
|
#ifdef CONFIG_VNC
|
|
|
|
qemu_opts_foreach(qemu_find_opts("vnc"),
|
|
|
|
vnc_init_func, NULL, &error_fatal);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (using_spice) {
|
|
|
|
qemu_spice.display_init();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-23 15:04:29 +03:00
|
|
|
static void qemu_init_board(void)
|
|
|
|
{
|
2020-10-21 17:25:06 +03:00
|
|
|
/* process plugin before CPUs are created, but once -smp has been parsed */
|
2020-10-27 11:58:26 +03:00
|
|
|
qemu_plugin_load_list(&plugin_list, &error_fatal);
|
2020-10-21 17:25:06 +03:00
|
|
|
|
2020-11-12 17:38:36 +03:00
|
|
|
/* From here on we enter MACHINE_PHASE_INITIALIZED. */
|
2022-04-14 19:52:59 +03:00
|
|
|
machine_run_board_init(current_machine, mem_path, &error_fatal);
|
2020-10-23 15:04:29 +03:00
|
|
|
|
2021-03-09 19:12:13 +03:00
|
|
|
drive_check_orphaned();
|
2020-10-23 15:04:29 +03:00
|
|
|
|
|
|
|
realtime_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qemu_create_cli_devices(void)
|
|
|
|
{
|
2021-10-08 16:34:42 +03:00
|
|
|
DeviceOption *opt;
|
|
|
|
|
2020-10-23 15:04:29 +03:00
|
|
|
soundhw_init();
|
|
|
|
|
|
|
|
qemu_opts_foreach(qemu_find_opts("fw_cfg"),
|
|
|
|
parse_fw_cfg, fw_cfg_find(), &error_fatal);
|
|
|
|
|
|
|
|
/* init USB devices */
|
|
|
|
if (machine_usb(current_machine)) {
|
|
|
|
if (foreach_device_config(DEV_USB, usb_parse) < 0)
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* init generic devices */
|
|
|
|
rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE);
|
|
|
|
qemu_opts_foreach(qemu_find_opts("device"),
|
|
|
|
device_init_func, NULL, &error_fatal);
|
2021-10-08 16:34:42 +03:00
|
|
|
QTAILQ_FOREACH(opt, &device_opts, next) {
|
2022-01-05 15:38:47 +03:00
|
|
|
DeviceState *dev;
|
2021-10-08 16:34:42 +03:00
|
|
|
loc_push_restore(&opt->loc);
|
|
|
|
/*
|
|
|
|
* TODO Eventually we should call qmp_device_add() here to make sure it
|
|
|
|
* behaves the same, but QMP still has to accept incorrectly typed
|
|
|
|
* options until libvirt is fixed and we want to be strict on the CLI
|
|
|
|
* from the start, so call qdev_device_add_from_qdict() directly for
|
|
|
|
* now.
|
|
|
|
*/
|
2022-01-05 15:38:47 +03:00
|
|
|
dev = qdev_device_add_from_qdict(opt->opts, true, &error_fatal);
|
|
|
|
object_unref(OBJECT(dev));
|
2021-10-08 16:34:42 +03:00
|
|
|
loc_pop(&opt->loc);
|
|
|
|
}
|
2020-10-23 15:04:29 +03:00
|
|
|
rom_reset_order_override();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qemu_machine_creation_done(void)
|
|
|
|
{
|
2020-10-20 09:01:19 +03:00
|
|
|
MachineState *machine = MACHINE(qdev_get_machine());
|
|
|
|
|
2020-10-23 15:04:29 +03:00
|
|
|
/* Did we create any drives that we failed to create a device for? */
|
|
|
|
drive_check_orphaned();
|
|
|
|
|
|
|
|
/* Don't warn about the default network setup that you get if
|
|
|
|
* no command line -net or -netdev options are specified. There
|
|
|
|
* are two cases that we would otherwise complain about:
|
|
|
|
* (1) board doesn't support a NIC but the implicit "-net nic"
|
|
|
|
* requested one
|
|
|
|
* (2) CONFIG_SLIRP not set, in which case the implicit "-net nic"
|
|
|
|
* sets up a nic that isn't connected to anything.
|
|
|
|
*/
|
|
|
|
if (!default_net && (!qtest_enabled() || has_defaults)) {
|
|
|
|
net_check_clients();
|
|
|
|
}
|
|
|
|
|
2020-10-27 11:26:14 +03:00
|
|
|
qdev_prop_check_globals();
|
|
|
|
|
2020-10-23 15:04:29 +03:00
|
|
|
qdev_machine_creation_done();
|
|
|
|
|
2020-10-20 09:01:19 +03:00
|
|
|
if (machine->cgs) {
|
|
|
|
/*
|
|
|
|
* Verify that Confidential Guest Support has actually been initialized
|
|
|
|
*/
|
|
|
|
assert(machine->cgs->ready);
|
|
|
|
}
|
|
|
|
|
2020-11-13 10:43:56 +03:00
|
|
|
if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
|
2020-10-23 15:04:29 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
2022-05-01 15:25:05 +03:00
|
|
|
if (!vga_interface_created && !default_vga &&
|
|
|
|
vga_interface_type != VGA_NONE) {
|
|
|
|
warn_report("A -vga option was passed but this machine "
|
|
|
|
"type does not use that option; "
|
|
|
|
"No VGA device has been created");
|
|
|
|
}
|
2020-10-23 15:04:29 +03:00
|
|
|
}
|
|
|
|
|
2020-10-27 15:44:23 +03:00
|
|
|
void qmp_x_exit_preconfig(Error **errp)
|
|
|
|
{
|
2020-11-12 17:38:36 +03:00
|
|
|
if (phase_check(PHASE_MACHINE_INITIALIZED)) {
|
2020-10-27 15:44:23 +03:00
|
|
|
error_setg(errp, "The command is permitted only before machine initialization");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
qemu_init_board();
|
|
|
|
qemu_create_cli_devices();
|
|
|
|
qemu_machine_creation_done();
|
|
|
|
|
|
|
|
if (loadvm) {
|
migration: preserve suspended for snapshot
Restoring a snapshot can break a suspended guest. Snapshots suffer from
the same suspended-state issues that affect live migration, plus they must
handle an additional problematic scenario, which is that a running vm must
remain running if it loads a suspended snapshot.
To save, the existing vm_stop call now completely stops the suspended
state. Finish with vm_resume to leave the vm in the state it had prior
to the save, correctly restoring the suspended state.
To load, if the snapshot is not suspended, then vm_stop + vm_resume
correctly handles all states, and leaves the vm in the state it had prior
to the load. However, if the snapshot is suspended, restoration is
trickier. First, call vm_resume to restore the state to suspended so the
current state matches the saved state. Then, if the pre-load state is
running, call wakeup to resume running.
Prior to these changes, the vm_stop to RUN_STATE_SAVE_VM and
RUN_STATE_RESTORE_VM did not change runstate if the current state was
suspended, but now it does, so allow these transitions.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/1704312341-66640-8-git-send-email-steven.sistare@oracle.com
Signed-off-by: Peter Xu <peterx@redhat.com>
2024-01-03 23:05:36 +03:00
|
|
|
RunState state = autostart ? RUN_STATE_RUNNING : runstate_get();
|
2021-07-20 15:53:53 +03:00
|
|
|
load_snapshot(loadvm, NULL, false, NULL, &error_fatal);
|
migration: preserve suspended for snapshot
Restoring a snapshot can break a suspended guest. Snapshots suffer from
the same suspended-state issues that affect live migration, plus they must
handle an additional problematic scenario, which is that a running vm must
remain running if it loads a suspended snapshot.
To save, the existing vm_stop call now completely stops the suspended
state. Finish with vm_resume to leave the vm in the state it had prior
to the save, correctly restoring the suspended state.
To load, if the snapshot is not suspended, then vm_stop + vm_resume
correctly handles all states, and leaves the vm in the state it had prior
to the load. However, if the snapshot is suspended, restoration is
trickier. First, call vm_resume to restore the state to suspended so the
current state matches the saved state. Then, if the pre-load state is
running, call wakeup to resume running.
Prior to these changes, the vm_stop to RUN_STATE_SAVE_VM and
RUN_STATE_RESTORE_VM did not change runstate if the current state was
suspended, but now it does, so allow these transitions.
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/1704312341-66640-8-git-send-email-steven.sistare@oracle.com
Signed-off-by: Peter Xu <peterx@redhat.com>
2024-01-03 23:05:36 +03:00
|
|
|
load_snapshot_resume(state);
|
2020-10-27 15:44:23 +03:00
|
|
|
}
|
|
|
|
if (replay_mode != REPLAY_MODE_NONE) {
|
|
|
|
replay_vmstate_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (incoming) {
|
|
|
|
Error *local_err = NULL;
|
|
|
|
if (strcmp(incoming, "defer") != 0) {
|
2023-10-23 21:20:48 +03:00
|
|
|
qmp_migrate_incoming(incoming, false, NULL, &local_err);
|
2020-10-27 15:44:23 +03:00
|
|
|
if (local_err) {
|
|
|
|
error_reportf_err(local_err, "-incoming %s: ", incoming);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (autostart) {
|
|
|
|
qmp_cont(NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-19 16:27:54 +03:00
|
|
|
void qemu_init(int argc, char **argv)
|
2003-06-24 17:42:40 +04:00
|
|
|
{
|
2020-10-27 18:08:04 +03:00
|
|
|
QemuOpts *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;
|
2014-03-05 21:30:47 +04:00
|
|
|
MachineClass *machine_class;
|
2012-05-02 20:07:29 +04:00
|
|
|
bool userconfig = true;
|
2014-06-20 17:26:08 +04:00
|
|
|
FILE *vmstate_dump_file = NULL;
|
2011-02-26 21:38:39 +03:00
|
|
|
|
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);
|
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);
|
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);
|
2020-12-11 19:52:41 +03:00
|
|
|
qemu_add_opts(&qemu_action_opts);
|
2023-09-01 13:12:58 +03:00
|
|
|
qemu_add_run_with_opts();
|
2016-02-16 23:59:07 +03:00
|
|
|
module_call_init(MODULE_INIT_OPTS);
|
2012-11-26 19:03:42 +04:00
|
|
|
|
2020-10-21 12:33:40 +03:00
|
|
|
error_init(argv[0]);
|
|
|
|
qemu_init_exec_dir(argv[0]);
|
2013-03-21 16:07:10 +04:00
|
|
|
|
2023-12-18 13:13:40 +03:00
|
|
|
os_setup_limits();
|
|
|
|
|
2022-02-03 18:58:33 +03:00
|
|
|
qemu_init_arch_modules();
|
2021-06-24 13:38:05 +03:00
|
|
|
|
2020-10-21 12:33:40 +03:00
|
|
|
qemu_init_subsystems();
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
machine_opts_dict = qdict_new();
|
2017-10-04 06:00:24 +03:00
|
|
|
if (userconfig) {
|
2021-02-26 20:08:16 +03:00
|
|
|
qemu_read_default_config_file(&error_fatal);
|
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:
|
2021-12-15 15:11:39 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("drive"),
|
|
|
|
optarg, false);
|
|
|
|
if (opts == NULL) {
|
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
|
|
|
exit(1);
|
|
|
|
}
|
2015-01-11 13:56:51 +03:00
|
|
|
break;
|
2009-07-31 14:25:36 +04:00
|
|
|
case QEMU_OPTION_set:
|
2021-05-24 13:57:51 +03:00
|
|
|
qemu_set_option(optarg, &error_fatal);
|
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:
|
2023-02-07 10:51:12 +03:00
|
|
|
snapshot = 1;
|
|
|
|
replay_add_blocker("-snapshot");
|
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:
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_put_str(machine_opts_dict, "graphics", "off");
|
2016-04-19 22:55:25 +03:00
|
|
|
nographic = true;
|
2018-02-02 14:10:14 +03:00
|
|
|
dpy.type = DISPLAY_TYPE_NONE;
|
2003-10-01 01:07:02 +04: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:
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_put_str(machine_opts_dict, "kernel", optarg);
|
2012-02-08 09:41:39 +04:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_initrd:
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_put_str(machine_opts_dict, "initrd", optarg);
|
2003-10-01 01:07:02 +04:00
|
|
|
break;
|
2004-05-14 02:02:20 +04:00
|
|
|
case QEMU_OPTION_append:
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_put_str(machine_opts_dict, "append", optarg);
|
2003-08-11 01:52:11 +04:00
|
|
|
break;
|
2012-03-02 15:56:38 +04:00
|
|
|
case QEMU_OPTION_dtb:
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_put_str(machine_opts_dict, "dtb", optarg);
|
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:
|
2022-04-14 19:52:57 +03:00
|
|
|
machine_parse_property_opt(qemu_find_opts("boot-opts"), "boot", optarg);
|
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:
|
2024-02-13 12:56:56 +03:00
|
|
|
qdict_put_str(machine_opts_dict, "fd-bootchk", "off");
|
2006-06-14 20:03:05 +04:00
|
|
|
break;
|
2009-10-08 22:58:26 +04:00
|
|
|
case QEMU_OPTION_netdev:
|
2016-05-12 17:17:16 +03:00
|
|
|
default_net = 0;
|
qapi: net: introduce a way to bypass qemu_opts_parse_noisily()
As qemu_opts_parse_noisily() flattens the QAPI structures ("type" field
of Netdev structure can collides with "type" field of SocketAddress),
we introduce a way to bypass qemu_opts_parse_noisily() and use directly
visit_type_Netdev() to parse the backend parameters.
More details from Markus:
qemu_init() passes the argument of -netdev, -nic, and -net to
net_client_parse().
net_client_parse() parses with qemu_opts_parse_noisily(), passing
QemuOptsList qemu_netdev_opts for -netdev, qemu_nic_opts for -nic, and
qemu_net_opts for -net. Their desc[] are all empty, which means any
keys are accepted. The result of the parse (a QemuOpts) is stored in
the QemuOptsList.
Note that QemuOpts is flat by design. In some places, we layer non-flat
on top using dotted keys convention, but not here.
net_init_clients() iterates over the stored QemuOpts, and passes them to
net_init_netdev(), net_param_nic(), or net_init_client(), respectively.
These functions pass the QemuOpts to net_client_init(). They also do
other things with the QemuOpts, which we can ignore here.
net_client_init() uses the opts visitor to convert the (flat) QemOpts to
a (non-flat) QAPI object Netdev. Netdev is also the argument of QMP
command netdev_add.
The opts visitor was an early attempt to support QAPI in
(QemuOpts-based) CLI. It restricts QAPI types to a certain shape; see
commit eb7ee2cbeb "qapi: introduce OptsVisitor".
A more modern way to support QAPI is qobject_input_visitor_new_str().
It uses keyval_parse() instead of QemuOpts for KEY=VALUE,... syntax, and
it also supports JSON syntax. The former isn't quite as expressive as
JSON, but it's a lot closer than QemuOpts + opts visitor.
This commit paves the way to use of the modern way instead.
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
2022-10-21 12:09:09 +03:00
|
|
|
if (netdev_is_modern(optarg)) {
|
|
|
|
netdev_parse_modern(optarg);
|
|
|
|
} else {
|
|
|
|
net_client_parse(qemu_find_opts("netdev"), optarg);
|
|
|
|
}
|
2009-10-08 22:58:26 +04:00
|
|
|
break;
|
2018-02-21 13:18:36 +03:00
|
|
|
case QEMU_OPTION_nic:
|
|
|
|
default_net = 0;
|
2022-10-21 12:09:08 +03:00
|
|
|
net_client_parse(qemu_find_opts("nic"), optarg);
|
2018-02-21 13:18:36 +03:00
|
|
|
break;
|
2005-11-16 01:16:05 +03:00
|
|
|
case QEMU_OPTION_net:
|
2016-05-12 17:17:16 +03:00
|
|
|
default_net = 0;
|
2022-10-21 12:09:08 +03:00
|
|
|
net_client_parse(qemu_find_opts("net"), optarg);
|
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
|
2019-03-09 01:34:15 +03:00
|
|
|
case QEMU_OPTION_audiodev:
|
2023-10-05 12:55:03 +03:00
|
|
|
default_audio = 0;
|
2019-03-09 01:34:15 +03:00
|
|
|
audio_parse_option(optarg);
|
|
|
|
break;
|
2022-04-27 13:27:46 +03:00
|
|
|
case QEMU_OPTION_audio: {
|
2022-09-08 11:14:41 +03:00
|
|
|
bool help;
|
2023-09-21 11:23:58 +03:00
|
|
|
char *model = NULL;
|
2022-04-27 13:27:46 +03:00
|
|
|
Audiodev *dev = NULL;
|
|
|
|
Visitor *v;
|
2022-09-08 11:14:41 +03:00
|
|
|
QDict *dict = keyval_parse(optarg, "driver", &help, &error_fatal);
|
2023-10-05 12:55:03 +03:00
|
|
|
default_audio = 0;
|
2022-09-08 11:14:41 +03:00
|
|
|
if (help || (qdict_haskey(dict, "driver") &&
|
|
|
|
is_help_option(qdict_get_str(dict, "driver")))) {
|
|
|
|
audio_help();
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
}
|
2022-04-27 13:27:46 +03:00
|
|
|
if (!qdict_haskey(dict, "id")) {
|
|
|
|
qdict_put_str(dict, "id", "audiodev0");
|
|
|
|
}
|
2023-09-21 11:23:58 +03:00
|
|
|
if (qdict_haskey(dict, "model")) {
|
|
|
|
model = g_strdup(qdict_get_str(dict, "model"));
|
|
|
|
qdict_del(dict, "model");
|
|
|
|
if (is_help_option(model)) {
|
|
|
|
show_valid_soundhw();
|
|
|
|
exit(0);
|
|
|
|
}
|
2022-04-27 14:15:23 +03:00
|
|
|
}
|
2022-04-27 13:27:46 +03:00
|
|
|
v = qobject_input_visitor_new_keyval(QOBJECT(dict));
|
|
|
|
qobject_unref(dict);
|
|
|
|
visit_type_Audiodev(v, NULL, &dev, &error_fatal);
|
|
|
|
visit_free(v);
|
2023-09-21 11:23:58 +03:00
|
|
|
if (model) {
|
|
|
|
audio_define(dev);
|
|
|
|
select_soundhw(model, dev->id);
|
|
|
|
g_free(model);
|
|
|
|
} else {
|
|
|
|
audio_define_default(dev, &error_fatal);
|
|
|
|
}
|
2005-10-30 21:58:22 +03:00
|
|
|
break;
|
2022-04-27 13:27:46 +03:00
|
|
|
}
|
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:
|
2022-08-05 13:01:51 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("memory"), optarg, true);
|
|
|
|
if (opts == NULL) {
|
|
|
|
exit(1);
|
|
|
|
}
|
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;
|
2023-01-12 18:20:13 +03:00
|
|
|
#if defined(CONFIG_TCG) && defined(CONFIG_LINUX)
|
|
|
|
case QEMU_OPTION_perfmap:
|
|
|
|
perf_enable_perfmap();
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_jitdump:
|
|
|
|
perf_enable_jitdump();
|
|
|
|
break;
|
|
|
|
#endif
|
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 {
|
2020-08-18 12:57:56 +03:00
|
|
|
qemu_add_data_dir(g_strdup(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:
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_put_str(machine_opts_dict, "firmware", optarg);
|
2007-10-05 17:08:35 +04:00
|
|
|
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;
|
2020-12-11 19:52:41 +03:00
|
|
|
case QEMU_OPTION_action:
|
|
|
|
olist = qemu_find_opts("action");
|
|
|
|
if (!qemu_opts_parse_noisily(olist, optarg, false)) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2021-10-27 16:03:04 +03:00
|
|
|
case QEMU_OPTION_watchdog_action: {
|
|
|
|
opts = qemu_opts_create(qemu_find_opts("action"), NULL, 0, &error_abort);
|
|
|
|
qemu_opt_set(opts, "watchdog", optarg, &error_abort);
|
2009-04-25 16:56:19 +04:00
|
|
|
break;
|
2021-10-27 16:03:04 +03:00
|
|
|
}
|
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;
|
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:
|
2024-02-20 19:09:30 +03:00
|
|
|
object_register_sugar_prop("ide-device", "win2k-install-hack", "true", true);
|
2005-04-30 20:10:35 +04:00
|
|
|
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:
|
2020-10-27 11:07:30 +03:00
|
|
|
preconfig_requested = true;
|
2018-05-11 20:24:43 +03:00
|
|
|
break;
|
2008-11-05 19:04:33 +03:00
|
|
|
case QEMU_OPTION_enable_kvm:
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_put_str(machine_opts_dict, "accel", "kvm");
|
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:
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
{
|
|
|
|
bool help;
|
|
|
|
|
|
|
|
keyval_parse_into(machine_opts_dict, optarg, "type", &help, &error_fatal);
|
|
|
|
if (help) {
|
|
|
|
machine_help_func(machine_opts_dict);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
}
|
|
|
|
break;
|
2010-09-21 23:05:31 +04:00
|
|
|
}
|
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
|
|
|
}
|
|
|
|
break;
|
2005-11-05 17:22:28 +03:00
|
|
|
case QEMU_OPTION_usb:
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_put_str(machine_opts_dict, "usb", "on");
|
2005-11-05 17:22:28 +03:00
|
|
|
break;
|
2005-11-06 19:13:29 +03:00
|
|
|
case QEMU_OPTION_usbdevice:
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qdict_put_str(machine_opts_dict, "usb", "on");
|
2009-07-15 15:59:26 +04:00
|
|
|
add_device_config(DEV_USB, optarg);
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_device:
|
2021-10-08 16:34:42 +03:00
|
|
|
if (optarg[0] == '{') {
|
|
|
|
QObject *obj = qobject_from_json(optarg, &error_fatal);
|
|
|
|
DeviceOption *opt = g_new0(DeviceOption, 1);
|
|
|
|
opt->opts = qobject_to(QDict, obj);
|
|
|
|
loc_save(&opt->loc);
|
|
|
|
assert(opt->opts != NULL);
|
|
|
|
QTAILQ_INSERT_TAIL(&device_opts, opt, next);
|
|
|
|
} else {
|
|
|
|
if (!qemu_opts_parse_noisily(qemu_find_opts("device"),
|
|
|
|
optarg, true)) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2009-07-31 14:25:37 +04:00
|
|
|
}
|
2005-11-06 19:13:29 +03:00
|
|
|
break;
|
2005-11-22 02:25:50 +03:00
|
|
|
case QEMU_OPTION_smp:
|
2021-07-20 15:54:07 +03:00
|
|
|
machine_parse_property_opt(qemu_find_opts("smp-opts"),
|
|
|
|
"smp", optarg);
|
2005-11-22 02:25:50 +03:00
|
|
|
break;
|
2023-10-25 16:05:08 +03:00
|
|
|
#ifdef CONFIG_VNC
|
2015-01-11 13:56:51 +03:00
|
|
|
case QEMU_OPTION_vnc:
|
2021-01-20 17:42:35 +03:00
|
|
|
vnc_parse(optarg);
|
2023-10-25 16:21:17 +03:00
|
|
|
display_remote++;
|
2011-03-16 15:33:36 +03:00
|
|
|
break;
|
2023-10-25 16:05:08 +03:00
|
|
|
#endif
|
2006-10-02 23:44:22 +04:00
|
|
|
case QEMU_OPTION_no_reboot:
|
2020-12-11 19:52:41 +03:00
|
|
|
olist = qemu_find_opts("action");
|
|
|
|
qemu_opts_parse_noisily(olist, "reboot=shutdown", false);
|
2006-10-02 23:44:22 +04:00
|
|
|
break;
|
2008-04-12 01:35:52 +04:00
|
|
|
case QEMU_OPTION_no_shutdown:
|
2020-12-11 19:52:41 +03:00
|
|
|
olist = qemu_find_opts("action");
|
2021-01-20 16:30:27 +03:00
|
|
|
qemu_opts_parse_noisily(olist, "shutdown=pause", false);
|
2008-04-12 01:35:52 +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);
|
|
|
|
}
|
2020-06-26 23:19:00 +03:00
|
|
|
/* Capture guest name if -msg guest-name is used later */
|
|
|
|
error_guest_name = qemu_opt_get(opts, "guest");
|
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-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:
|
2023-01-24 13:59:49 +03:00
|
|
|
if (!(accel_find("xen")) && !(accel_find("kvm"))) {
|
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:
|
2021-07-30 13:59:40 +03:00
|
|
|
if (!(accel_find("xen"))) {
|
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:
|
2021-07-30 13:59:40 +03:00
|
|
|
if (!(accel_find("xen"))) {
|
2017-03-22 12:39:15 +03:00
|
|
|
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:
|
2020-11-02 14:58:41 +03:00
|
|
|
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:
|
2021-05-24 13:57:51 +03:00
|
|
|
qemu_read_config_file(optarg, qemu_parse_config_group, &error_fatal);
|
2021-02-26 20:08:16 +03:00
|
|
|
break;
|
2021-09-09 11:44:11 +03:00
|
|
|
#ifdef CONFIG_SPICE
|
2010-03-11 17:13:27 +03:00
|
|
|
case QEMU_OPTION_spice:
|
2023-10-25 15:52:56 +03:00
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("spice"), 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;
|
2021-09-09 11:44:11 +03:00
|
|
|
#endif
|
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:
|
2021-03-12 20:35:46 +03:00
|
|
|
object_option_parse(optarg);
|
2012-06-25 23:36:33 +04:00
|
|
|
break;
|
2018-06-22 22:22:05 +03:00
|
|
|
case QEMU_OPTION_overcommit:
|
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("overcommit"),
|
|
|
|
optarg, false);
|
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2020-12-10 18:58:07 +03:00
|
|
|
enable_mlock = qemu_opt_get_bool(opts, "mem-lock", false);
|
2018-06-22 22:22:05 +03:00
|
|
|
enable_cpu_pm = qemu_opt_get_bool(opts, "cpu-pm", false);
|
2013-04-19 18:42:06 +04:00
|
|
|
break;
|
2021-03-18 18:55:10 +03:00
|
|
|
case QEMU_OPTION_compat:
|
|
|
|
{
|
2023-09-25 13:22:50 +03:00
|
|
|
CompatPolicy *opts_policy;
|
2021-03-18 18:55:10 +03:00
|
|
|
Visitor *v;
|
|
|
|
|
|
|
|
v = qobject_input_visitor_new_str(optarg, NULL,
|
|
|
|
&error_fatal);
|
|
|
|
|
2023-09-25 13:22:50 +03:00
|
|
|
visit_type_CompatPolicy(v, NULL, &opts_policy, &error_fatal);
|
|
|
|
QAPI_CLONE_MEMBERS(CompatPolicy, &compat_policy, opts_policy);
|
2021-03-18 18:55:10 +03:00
|
|
|
|
2023-09-25 13:22:50 +03:00
|
|
|
qapi_free_CompatPolicy(opts_policy);
|
2021-03-18 18:55:10 +03:00
|
|
|
visit_free(v);
|
|
|
|
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;
|
2023-09-01 13:12:58 +03:00
|
|
|
#if defined(CONFIG_POSIX)
|
|
|
|
case QEMU_OPTION_runas:
|
|
|
|
if (!os_set_runas(optarg)) {
|
|
|
|
error_report("User \"%s\" doesn't exist"
|
|
|
|
" (and is not <uid>:<gid>)",
|
|
|
|
optarg);
|
2018-05-04 20:01:07 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
2023-09-01 13:12:58 +03:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_daemonize:
|
|
|
|
os_set_daemonize(true);
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_run_with: {
|
|
|
|
const char *str;
|
|
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("run-with"),
|
|
|
|
optarg, false);
|
|
|
|
if (!opts) {
|
2018-05-04 20:01:07 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
2023-09-01 13:12:58 +03:00
|
|
|
#if defined(CONFIG_LINUX)
|
|
|
|
if (qemu_opt_get_bool(opts, "async-teardown", false)) {
|
|
|
|
init_async_teardown();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
str = qemu_opt_get(opts, "chroot");
|
|
|
|
if (str) {
|
|
|
|
os_set_chroot(str);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_POSIX */
|
|
|
|
|
|
|
|
default:
|
|
|
|
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
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qemu_validate_options(machine_opts_dict);
|
2020-10-21 17:21:22 +03:00
|
|
|
qemu_process_sugar_options();
|
2020-11-03 11:45:26 +03:00
|
|
|
|
2020-03-13 20:24:47 +03:00
|
|
|
/*
|
2020-10-21 12:17:39 +03:00
|
|
|
* These options affect everything else and should be processed
|
|
|
|
* before daemonizing.
|
2020-03-13 20:24:47 +03:00
|
|
|
*/
|
2020-10-21 12:17:39 +03:00
|
|
|
qemu_process_early_options();
|
2020-03-13 20:24:47 +03:00
|
|
|
|
2020-10-21 12:17:39 +03:00
|
|
|
qemu_process_help_options();
|
|
|
|
qemu_maybe_daemonize(pid_file);
|
|
|
|
|
vl.c: do not execute trace_init_backends() before daemonizing
Commit v5.2.0-190-g0546c0609c ("vl: split various early command line
options to a separate function") moved the trace backend init code to
the qemu_process_early_options(). Which is now being called before
os_daemonize() via qemu_maybe_daemonize().
Turns out that this change of order causes a problem when executing
QEMU in daemon mode and with CONFIG_TRACE_SIMPLE. The trace thread
is now being created by the parent, and the parent is left waiting for
a trace file flush that was registered via st_init(). The result is
that the parent process never exits.
To reproduce, fire up a QEMU process with -daemonize and with
CONFIG_TRACE_SIMPLE enabled. Two QEMU process will be left in the
host:
$ sudo ./x86_64-softmmu/qemu-system-x86_64 -S -no-user-config -nodefaults \
-nographic -machine none,accel=kvm:tcg -daemonize
$ ps axf | grep qemu
529710 pts/3 S+ 0:00 | \_ grep --color=auto qemu
529697 ? Ssl 0:00 \_ ./x86_64-softmmu/qemu-system-x86_64 -S -no-user-config -nodefaults -nographic -machine none,accel=kvm:tcg -daemonize
529699 ? Sl 0:00 \_ ./x86_64-softmmu/qemu-system-x86_64 -S -no-user-config -nodefaults -nographic -machine none,accel=kvm:tcg -daemonize
The parent thread is hang in flush_trace_file:
$ sudo gdb ./x86_64-softmmu/qemu-system-x86_64 529697
(..)
(gdb) bt
#0 0x00007f9dac6a137d in syscall () at /lib64/libc.so.6
#1 0x00007f9dacc3c4f3 in g_cond_wait () at /lib64/libglib-2.0.so.0
#2 0x0000555d12f952da in flush_trace_file (wait=true) at ../trace/simple.c:140
#3 0x0000555d12f95b4c in st_flush_trace_buffer () at ../trace/simple.c:383
#4 0x00007f9dac5e43a7 in __run_exit_handlers () at /lib64/libc.so.6
#5 0x00007f9dac5e4550 in on_exit () at /lib64/libc.so.6
#6 0x0000555d12d454de in os_daemonize () at ../os-posix.c:255
#7 0x0000555d12d0bd5c in qemu_maybe_daemonize (pid_file=0x0) at ../softmmu/vl.c:2408
#8 0x0000555d12d0e566 in qemu_init (argc=8, argv=0x7fffc594d9b8, envp=0x7fffc594da00) at ../softmmu/vl.c:3459
#9 0x0000555d128edac1 in main (argc=8, argv=0x7fffc594d9b8, envp=0x7fffc594da00) at ../softmmu/main.c:49
(gdb)
Aside from the 'zombie' process in the host, this is directly impacting
Libvirt. Libvirt waits for the parent process to exit to be sure that the
QMP monitor is available in the daemonized process to fetch QEMU
capabilities, and as is now Libvirt hangs at daemon start waiting
for the parent thread to exit.
The fix is simple: just move the trace backend related code back to
be executed after daemonizing.
Fixes: 0546c0609cb5a8d90c1cbac8e0d64b5a048bbb19
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20210105181437.538366-2-danielhb413@gmail.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-01-05 21:14:37 +03:00
|
|
|
/*
|
|
|
|
* The trace backend must be initialized after daemonizing.
|
|
|
|
* trace_init_backends() will call st_init(), which will create the
|
|
|
|
* trace thread in the parent, and also register st_flush_trace_buffer()
|
|
|
|
* in atexit(). This function will force the parent to wait for the
|
|
|
|
* writeout thread to finish, which will not occur, and the parent
|
|
|
|
* process will be left in the host.
|
|
|
|
*/
|
|
|
|
if (!trace_init_backends()) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
trace_init_file();
|
|
|
|
|
2020-10-21 12:33:40 +03:00
|
|
|
qemu_init_main_loop(&error_fatal);
|
|
|
|
cpu_timers_init();
|
2020-03-13 20:24:47 +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-10-18 10:12:54 +03:00
|
|
|
configure_rtc(qemu_find_opts_singleton("rtc"));
|
|
|
|
|
2022-08-05 13:01:51 +03:00
|
|
|
/* Transfer QemuOpts options into machine options */
|
|
|
|
parse_memory_options();
|
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qemu_create_machine(machine_opts_dict);
|
2010-11-22 18:44:15 +03:00
|
|
|
|
2020-11-30 21:44:49 +03:00
|
|
|
suspend_mux_open();
|
|
|
|
|
2020-10-21 13:22:39 +03:00
|
|
|
qemu_disable_default_devices();
|
2023-10-18 16:16:32 +03:00
|
|
|
qemu_setup_display();
|
2020-10-21 13:22:39 +03:00
|
|
|
qemu_create_default_devices();
|
2020-10-21 17:41:18 +03:00
|
|
|
qemu_create_early_backends();
|
2019-03-08 16:14:40 +03:00
|
|
|
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
qemu_apply_legacy_machine_options(machine_opts_dict);
|
|
|
|
qemu_apply_machine_options(machine_opts_dict);
|
|
|
|
qobject_unref(machine_opts_dict);
|
2020-11-12 17:38:36 +03:00
|
|
|
phase_advance(PHASE_MACHINE_CREATED);
|
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
|
vl: switch -M parsing to keyval
Switch from QemuOpts to keyval. This enables the introduction
of non-scalar machine properties, and JSON syntax in the future.
For JSON syntax to be supported right now, we would have to
consider what would happen if string-based dictionaries (produced by
-M key=val) were to be merged with strongly-typed dictionaries
(produced by -M {'key': 123}).
The simplest way out is to never enter the situation, and only allow one
-M option when JSON syntax is in use. However, we want options such as
-smp to become syntactic sugar for -M, and this is a problem; as soon
as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
together with -smp. Therefore, allowing JSON syntax right now for -M
would be a forward-compatibility nightmare and it would be impossible
anyway to introduce -M incrementally in tools.
Instead, support for JSON syntax is delayed until after the main
options are converted to QOM compound properties. These include -boot,
-acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg. Once JSON
syntax is introduced, these options will _also_ be forbidden together
with -M '{...}'.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-05-13 18:28:34 +03:00
|
|
|
* after qemu_apply_machine_options.
|
2019-04-01 12:08:26 +03:00
|
|
|
*/
|
2019-11-13 11:59:04 +03:00
|
|
|
configure_accelerators(argv[0]);
|
2020-11-12 17:38:36 +03:00
|
|
|
phase_advance(PHASE_ACCEL_CREATED);
|
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(),
|
2021-02-04 19:39:25 +03:00
|
|
|
* called from do_configure_accelerator().
|
2019-04-01 12:08:26 +03:00
|
|
|
*/
|
|
|
|
|
2020-10-27 18:04:37 +03:00
|
|
|
machine_class = MACHINE_GET_CLASS(current_machine);
|
2018-06-25 12:05:12 +03:00
|
|
|
if (!qtest_enabled() && machine_class->deprecation_reason) {
|
2022-05-11 20:50:43 +03:00
|
|
|
warn_report("Machine type '%s' is deprecated: %s",
|
2018-06-25 12:05:12 +03:00
|
|
|
machine_class->name, machine_class->deprecation_reason);
|
|
|
|
}
|
|
|
|
|
2023-04-19 19:17:37 +03:00
|
|
|
/*
|
|
|
|
* Create backends before creating migration objects, so that it can
|
|
|
|
* check against compatibilities on the backend memories (e.g. postcopy
|
|
|
|
* over memory-backend-file objects).
|
|
|
|
*/
|
|
|
|
qemu_create_late_backends();
|
2024-01-31 19:53:27 +03:00
|
|
|
phase_advance(PHASE_LATE_BACKENDS_CREATED);
|
2023-04-19 19:17:37 +03:00
|
|
|
|
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();
|
|
|
|
|
2017-09-13 19:04:55 +03:00
|
|
|
/* parse features once if machine provides default cpu_type */
|
2023-11-16 19:33:12 +03:00
|
|
|
current_machine->cpu_type = machine_class_default_cpu_type(machine_class);
|
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
|
|
|
}
|
2021-02-04 19:39:25 +03:00
|
|
|
/* NB: for machine none cpu_type could STILL be NULL here! */
|
2020-02-19 19:08:40 +03:00
|
|
|
|
2020-10-27 18:16:18 +03:00
|
|
|
qemu_resolve_machine_memdev();
|
2018-01-10 18:22:50 +03:00
|
|
|
parse_numa_opts(current_machine);
|
2017-09-13 19:04:55 +03:00
|
|
|
|
2014-06-20 17:26:08 +04:00
|
|
|
if (vmstate_dump_file) {
|
|
|
|
/* dump and exit */
|
2021-11-16 10:28:40 +03:00
|
|
|
module_load_qom_all();
|
2014-06-20 17:26:08 +04:00
|
|
|
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
|
|
|
}
|
2006-12-21 22:46:43 +03:00
|
|
|
|
2020-10-27 15:44:23 +03:00
|
|
|
if (!preconfig_requested) {
|
|
|
|
qmp_x_exit_preconfig(&error_fatal);
|
|
|
|
}
|
2020-12-17 12:10:12 +03:00
|
|
|
qemu_init_displays();
|
2018-03-09 15:02:50 +03:00
|
|
|
accel_setup_post(current_machine);
|
2010-06-10 13:42:28 +04:00
|
|
|
os_setup_post();
|
2020-11-30 21:44:49 +03:00
|
|
|
resume_mux_open();
|
2020-02-20 07:10:58 +03:00
|
|
|
}
|