2003-06-24 15:42:40 +02:00
|
|
|
/*
|
2004-03-14 13:20:30 +01:00
|
|
|
* QEMU System Emulator
|
2007-09-16 23:08:06 +02:00
|
|
|
*
|
2008-01-06 18:21:48 +01:00
|
|
|
* Copyright (c) 2003-2008 Fabrice Bellard
|
2007-09-16 23:08:06 +02:00
|
|
|
*
|
2003-06-25 18:20:35 +02: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 15:42:40 +02:00
|
|
|
*/
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <errno.h>
|
2004-04-01 01:37:16 +02:00
|
|
|
#include <sys/time.h>
|
|
|
|
|
2009-03-07 17:52:02 +01:00
|
|
|
#include "config-host.h"
|
|
|
|
|
2012-08-14 23:44:07 +02:00
|
|
|
#ifdef CONFIG_SECCOMP
|
2012-12-17 18:20:04 +01:00
|
|
|
#include "sysemu/seccomp.h"
|
2012-08-14 23:44:07 +02:00
|
|
|
#endif
|
|
|
|
|
2008-07-19 11:56:24 +02:00
|
|
|
#if defined(CONFIG_VDE)
|
|
|
|
#include <libvdeplug.h>
|
|
|
|
#endif
|
|
|
|
|
2004-04-04 22:22:28 +02:00
|
|
|
#ifdef CONFIG_SDL
|
2009-06-18 20:11:03 +02:00
|
|
|
#if defined(__APPLE__) || defined(main)
|
2009-06-13 13:19:11 +02:00
|
|
|
#include <SDL.h>
|
2009-02-15 21:18:41 +01:00
|
|
|
int qemu_main(int argc, char **argv, char **envp);
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
2009-06-18 20:11:03 +02:00
|
|
|
return qemu_main(argc, argv, NULL);
|
2009-02-15 21:18:41 +01:00
|
|
|
}
|
|
|
|
#undef main
|
|
|
|
#define main qemu_main
|
2004-07-10 18:26:15 +02:00
|
|
|
#endif
|
2004-04-04 22:22:28 +02:00
|
|
|
#endif /* CONFIG_SDL */
|
2003-06-24 15:42:40 +02:00
|
|
|
|
2005-03-01 22:37:28 +01:00
|
|
|
#ifdef CONFIG_COCOA
|
|
|
|
#undef main
|
|
|
|
#define main qemu_main
|
|
|
|
#endif /* CONFIG_COCOA */
|
|
|
|
|
2011-08-22 15:12:52 +02:00
|
|
|
#include <glib.h>
|
|
|
|
|
2014-03-18 16:26:35 +01:00
|
|
|
#include "qemu/sockets.h"
|
2009-03-07 16:32:56 +01:00
|
|
|
#include "hw/hw.h"
|
|
|
|
#include "hw/boards.h"
|
2014-09-26 22:45:17 +02:00
|
|
|
#include "sysemu/accel.h"
|
2009-03-07 16:32:56 +01:00
|
|
|
#include "hw/usb.h"
|
2013-02-05 17:06:20 +01:00
|
|
|
#include "hw/i386/pc.h"
|
|
|
|
#include "hw/isa/isa.h"
|
2009-03-07 16:32:56 +01:00
|
|
|
#include "hw/bt.h"
|
2013-02-05 17:06:20 +01:00
|
|
|
#include "sysemu/watchdog.h"
|
|
|
|
#include "hw/i386/smbios.h"
|
|
|
|
#include "hw/xen/xen.h"
|
2009-07-15 13:59:26 +02:00
|
|
|
#include "hw/qdev.h"
|
2009-10-01 16:42:33 +02:00
|
|
|
#include "hw/loader.h"
|
2013-02-04 11:37:52 +01:00
|
|
|
#include "monitor/qdev.h"
|
2013-04-08 16:55:25 +02:00
|
|
|
#include "sysemu/bt.h"
|
2012-10-24 08:43:34 +02:00
|
|
|
#include "net/net.h"
|
2009-11-25 19:48:54 +01:00
|
|
|
#include "net/slirp.h"
|
2012-12-17 18:19:49 +01:00
|
|
|
#include "monitor/monitor.h"
|
2012-11-28 12:06:30 +01:00
|
|
|
#include "ui/console.h"
|
2012-12-17 18:20:04 +01:00
|
|
|
#include "sysemu/sysemu.h"
|
2015-02-08 19:51:16 +01:00
|
|
|
#include "sysemu/numa.h"
|
2012-12-17 18:19:49 +01:00
|
|
|
#include "exec/gdbstub.h"
|
2012-12-17 18:20:00 +01:00
|
|
|
#include "qemu/timer.h"
|
2013-04-08 16:55:25 +02:00
|
|
|
#include "sysemu/char.h"
|
2014-02-07 09:26:14 +01:00
|
|
|
#include "qemu/bitmap.h"
|
2012-12-17 18:20:04 +01:00
|
|
|
#include "sysemu/blockdev.h"
|
2013-02-05 17:06:20 +01:00
|
|
|
#include "hw/block/block.h"
|
2012-12-17 18:19:50 +01:00
|
|
|
#include "migration/block.h"
|
2013-04-02 18:28:41 +02:00
|
|
|
#include "sysemu/tpm.h"
|
2012-12-17 18:20:04 +01:00
|
|
|
#include "sysemu/dma.h"
|
2009-03-07 16:32:56 +01:00
|
|
|
#include "audio/audio.h"
|
2012-12-17 18:19:50 +01:00
|
|
|
#include "migration/migration.h"
|
2012-12-17 18:20:04 +01:00
|
|
|
#include "sysemu/kvm.h"
|
2012-12-17 18:19:43 +01:00
|
|
|
#include "qapi/qmp/qjson.h"
|
2012-12-17 18:20:00 +01:00
|
|
|
#include "qemu/option.h"
|
|
|
|
#include "qemu/config-file.h"
|
2010-06-10 11:42:25 +02:00
|
|
|
#include "qemu-options.h"
|
2011-09-12 22:54:20 +02:00
|
|
|
#include "qmp-commands.h"
|
2012-12-17 18:20:00 +01:00
|
|
|
#include "qemu/main-loop.h"
|
2010-06-14 22:34:41 +02:00
|
|
|
#ifdef CONFIG_VIRTFS
|
2010-04-29 14:14:43 +02:00
|
|
|
#include "fsdev/qemu-fsdev.h"
|
|
|
|
#endif
|
2012-12-17 18:20:04 +01:00
|
|
|
#include "sysemu/qtest.h"
|
2009-03-07 16:32:56 +01:00
|
|
|
|
2012-10-24 11:12:21 +02:00
|
|
|
#include "disas/disas.h"
|
2003-06-30 12:03:06 +02:00
|
|
|
|
2009-03-07 16:32:56 +01:00
|
|
|
|
2009-06-24 14:42:30 +02:00
|
|
|
#include "slirp/libslirp.h"
|
2009-03-07 16:32:56 +01:00
|
|
|
|
2010-11-16 13:20:25 +01:00
|
|
|
#include "trace.h"
|
2011-08-31 20:31:03 +02:00
|
|
|
#include "trace/control.h"
|
2012-12-17 18:20:00 +01:00
|
|
|
#include "qemu/queue.h"
|
2012-12-17 18:20:04 +01:00
|
|
|
#include "sysemu/cpus.h"
|
|
|
|
#include "sysemu/arch_init.h"
|
2012-12-17 18:20:00 +01:00
|
|
|
#include "qemu/osdep.h"
|
2009-09-12 09:36:22 +02:00
|
|
|
|
2010-03-11 15:13:27 +01:00
|
|
|
#include "ui/qemu-spice.h"
|
2012-06-25 21:36:33 +02:00
|
|
|
#include "qapi/string-input-visitor.h"
|
2014-06-10 13:15:15 +02:00
|
|
|
#include "qapi/opts-visitor.h"
|
2014-06-18 08:43:33 +02:00
|
|
|
#include "qom/object_interfaces.h"
|
|
|
|
#include "qapi-event.h"
|
2010-03-11 15:13:27 +01: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 20:06:52 +01:00
|
|
|
#define MAX_VIRTIO_CONSOLES 1
|
2013-01-24 12:18:52 +01:00
|
|
|
#define MAX_SCLP_CONSOLES 1
|
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 20:06:52 +01:00
|
|
|
|
2013-03-08 11:42:24 +01:00
|
|
|
static const char *data_dir[16];
|
|
|
|
static int data_dir_idx;
|
2007-10-05 15:08:35 +02:00
|
|
|
const char *bios_name = NULL;
|
2008-09-28 02:42:12 +02:00
|
|
|
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
|
2009-05-21 23:54:00 +02:00
|
|
|
DisplayType display_type = DT_DEFAULT;
|
2014-11-11 16:54:45 +01:00
|
|
|
int request_opengl = -1;
|
2014-11-20 09:49:44 +01:00
|
|
|
int display_opengl;
|
2012-10-28 12:04:47 +01:00
|
|
|
static int display_remote;
|
2004-12-12 17:56:30 +01:00
|
|
|
const char* keyboard_layout = NULL;
|
2009-10-01 23:12:16 +02:00
|
|
|
ram_addr_t ram_size;
|
2010-03-02 00:25:08 +01:00
|
|
|
const char *mem_path = NULL;
|
|
|
|
int mem_prealloc = 0; /* force preallocation of physical target memory */
|
2014-09-23 12:42:24 +02:00
|
|
|
bool enable_mlock = false;
|
2004-03-14 22:44:30 +01:00
|
|
|
int nb_nics;
|
2005-11-15 23:16:05 +01:00
|
|
|
NICInfo nd_table[MAX_NICS];
|
2009-07-27 23:17:51 +02:00
|
|
|
int autostart;
|
2008-02-17 12:42:19 +01:00
|
|
|
static int rtc_utc = 1;
|
|
|
|
static int rtc_date_offset = -1; /* -1 means no change */
|
2013-08-21 17:03:04 +02:00
|
|
|
QEMUClockType rtc_clock;
|
2009-12-08 13:11:45 +01:00
|
|
|
int vga_interface_type = VGA_NONE;
|
2008-10-01 21:38:09 +02:00
|
|
|
static int full_screen = 0;
|
|
|
|
static int no_frame = 0;
|
2006-12-11 03:08:05 +01:00
|
|
|
int no_quit = 0;
|
2014-03-12 08:33:50 +01:00
|
|
|
#ifdef CONFIG_GTK
|
|
|
|
static bool grab_on_hover;
|
|
|
|
#endif
|
2004-08-24 23:13:40 +02:00
|
|
|
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
|
2005-01-15 13:02:56 +01:00
|
|
|
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
|
2009-01-15 21:05:25 +01:00
|
|
|
CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
|
2013-01-24 12:18:52 +01:00
|
|
|
CharDriverState *sclp_hds[MAX_SCLP_CONSOLES];
|
2005-04-30 18:10:35 +02:00
|
|
|
int win2k_install_hack = 0;
|
2009-04-05 22:08:59 +02:00
|
|
|
int singlestep = 0;
|
2005-11-22 00:25:50 +01:00
|
|
|
int smp_cpus = 1;
|
2009-07-23 17:03:42 +02:00
|
|
|
int max_cpus = 0;
|
extend -smp parsing to include cores= and threads= options
For injecting multi-core and multi-threading CPU topology into guests
extend the -smp syntax to accommodate cores and threads specification.
Syntax: -smp smp_value[,cores=nr_cores][,threads=nr_threads]\
[,socket=nr_sockets][,maxcpus=max_cpus]
smp_value is the legacy value specifying the total number of vCPUs for
the guest. If you specify one of cores, threads or sockets this value
can be omitted. Missing values will be computed to fulfill:
smp_value = nr_cores * nr_threads * nr_sockets
where it will favour sockets over cores over threads (to mimic the
current behavior, which will only inject multiple sockets.)
So -smp 4,threads=2 will inject two sockets with 2 threads each,
-smp cores=4 is an abbreviation for -smp 4,cores=4,threads=1,sockets=1.
If max_cpus (the number of hotpluggable CPUs) is omitted, it will
be set to smp_value.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-08-19 15:42:40 +02:00
|
|
|
int smp_cores = 1;
|
|
|
|
int smp_threads = 1;
|
2006-05-04 00:02:44 +02:00
|
|
|
int acpi_enabled = 1;
|
2008-12-18 00:28:44 +01:00
|
|
|
int no_hpet = 0;
|
2006-06-14 18:03:05 +02:00
|
|
|
int fd_bootchk = 1;
|
2012-10-28 12:04:47 +01:00
|
|
|
static int no_reboot;
|
2008-04-11 23:35:52 +02:00
|
|
|
int no_shutdown = 0;
|
2007-05-01 03:34:14 +02:00
|
|
|
int cursor_hide = 1;
|
2007-04-30 03:48:07 +02:00
|
|
|
int graphic_rotate = 0;
|
2009-08-21 10:31:34 +02:00
|
|
|
const char *watchdog;
|
2010-12-08 12:35:07 +01:00
|
|
|
QEMUOptionRom option_rom[MAX_OPTION_ROMS];
|
2007-01-05 18:39:04 +01:00
|
|
|
int nb_option_roms;
|
2007-01-20 18:12:09 +01:00
|
|
|
int semihosting_enabled = 0;
|
2007-07-28 00:08:46 +02:00
|
|
|
int old_param = 0;
|
2007-03-19 16:17:08 +01:00
|
|
|
const char *qemu_name;
|
2007-06-21 23:08:02 +02:00
|
|
|
int alt_grab = 0;
|
2009-09-17 22:48:04 +02:00
|
|
|
int ctrl_grab = 0;
|
2007-05-01 16:16:52 +02:00
|
|
|
unsigned int nb_prom_envs = 0;
|
|
|
|
const char *prom_envs[MAX_PROM_ENVS];
|
2009-07-02 00:19:02 +02:00
|
|
|
int boot_menu;
|
2014-10-07 10:00:05 +02:00
|
|
|
bool boot_strict;
|
2011-07-27 12:04:55 +02:00
|
|
|
uint8_t *boot_splash_filedata;
|
2013-01-23 18:25:08 +01:00
|
|
|
size_t boot_splash_filedata_size;
|
2011-07-27 12:04:55 +02:00
|
|
|
uint8_t qemu_extra_params_fw[2];
|
2003-06-24 15:42:40 +02:00
|
|
|
|
2014-07-25 11:56:29 +02:00
|
|
|
int icount_align_option;
|
2010-12-08 12:35:05 +01:00
|
|
|
|
smbios: Encode UUID according to SMBIOS specification
Differently from older versions, SMBIOS version 2.6 is explicit about
the encoding of UUID fields:
> Although RFC 4122 recommends network byte order for all fields, the PC
> industry (including the ACPI, UEFI, and Microsoft specifications) has
> consistently used little-endian byte encoding for the first three fields:
> time_low, time_mid, time_hi_and_version. The same encoding, also known as
> wire format, should also be used for the SMBIOS representation of the UUID.
>
> The UUID {00112233-4455-6677-8899-AABBCCDDEEFF} would thus be represented
> as 33 22 11 00 55 44 77 66 88 99 AA BB CC DD EE FF.
The dmidecode tool implements this and decodes the above "wire format"
when SMBIOS version >= 2.6. We moved from SMBIOS version 2.4 to 2.8 when
we started building the SMBIOS entry point inside QEMU, on commit
c97294ec1b9e36887e119589d456557d72ab37b5.
Change smbios_build_type_1_table() to encode the UUID as specified.
To make sure we won't change the guest-visible UUID when upgrading to a
newer QEMU version, keep the old behavior on pc-*-2.1 and older.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-10-29 14:26:08 +01:00
|
|
|
/* The bytes in qemu_uuid[] are in the order specified by RFC4122, _not_ in the
|
|
|
|
* little-endian "wire format" described in the SMBIOS 2.6 specification.
|
|
|
|
*/
|
2008-09-18 20:29:08 +02:00
|
|
|
uint8_t qemu_uuid[16];
|
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 15:18:31 +02:00
|
|
|
bool qemu_uuid_set;
|
2008-09-18 20:29:08 +02:00
|
|
|
|
2010-06-04 14:08:07 +02:00
|
|
|
static NotifierList exit_notifiers =
|
|
|
|
NOTIFIER_LIST_INITIALIZER(exit_notifiers);
|
|
|
|
|
2010-12-08 12:35:08 +01:00
|
|
|
static NotifierList machine_init_done_notifiers =
|
|
|
|
NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
|
|
|
|
|
2013-01-24 06:03:27 +01:00
|
|
|
bool xen_allowed;
|
2010-03-29 21:23:49 +02:00
|
|
|
uint32_t xen_domid;
|
|
|
|
enum xen_mode xen_mode = XEN_EMULATE;
|
|
|
|
|
2014-03-10 15:37:40 +01:00
|
|
|
static int has_defaults = 1;
|
2009-12-08 13:11:41 +01:00
|
|
|
static int default_serial = 1;
|
2009-12-08 13:11:42 +01:00
|
|
|
static int default_parallel = 1;
|
2009-12-08 13:11:54 +01:00
|
|
|
static int default_virtcon = 1;
|
2013-01-24 12:18:52 +01:00
|
|
|
static int default_sclp = 1;
|
2009-12-08 13:11:43 +01:00
|
|
|
static int default_monitor = 1;
|
2009-12-16 14:25:39 +01:00
|
|
|
static int default_floppy = 1;
|
|
|
|
static int default_cdrom = 1;
|
|
|
|
static int default_sdcard = 1;
|
2012-05-10 09:39:17 +02:00
|
|
|
static int default_vga = 1;
|
2009-12-08 13:11:41 +01:00
|
|
|
|
|
|
|
static struct {
|
|
|
|
const char *driver;
|
|
|
|
int *flag;
|
|
|
|
} default_list[] = {
|
2009-12-08 13:11:42 +01:00
|
|
|
{ .driver = "isa-serial", .flag = &default_serial },
|
|
|
|
{ .driver = "isa-parallel", .flag = &default_parallel },
|
2009-12-16 14:25:40 +01:00
|
|
|
{ .driver = "isa-fdc", .flag = &default_floppy },
|
2011-05-18 18:31:02 +02:00
|
|
|
{ .driver = "ide-cd", .flag = &default_cdrom },
|
|
|
|
{ .driver = "ide-hd", .flag = &default_cdrom },
|
2009-12-16 14:25:40 +01:00
|
|
|
{ .driver = "ide-drive", .flag = &default_cdrom },
|
2011-05-18 18:31:02 +02:00
|
|
|
{ .driver = "scsi-cd", .flag = &default_cdrom },
|
2010-01-21 11:49:23 +01:00
|
|
|
{ .driver = "virtio-serial-pci", .flag = &default_virtcon },
|
|
|
|
{ .driver = "virtio-serial-s390", .flag = &default_virtcon },
|
|
|
|
{ .driver = "virtio-serial", .flag = &default_virtcon },
|
2012-05-10 09:39:17 +02: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 14:28:48 +02:00
|
|
|
{ .driver = "virtio-vga", .flag = &default_vga },
|
2009-12-08 13:11:41 +01:00
|
|
|
};
|
|
|
|
|
2012-11-26 16:03:42 +01:00
|
|
|
static QemuOptsList qemu_rtc_opts = {
|
|
|
|
.name = "rtc",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
|
|
|
|
.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_sandbox_opts = {
|
|
|
|
.name = "sandbox",
|
|
|
|
.implied_opt_name = "enable",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_sandbox_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "enable",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static QemuOptsList qemu_trace_opts = {
|
|
|
|
.name = "trace",
|
|
|
|
.implied_opt_name = "trace",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "events",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},{
|
|
|
|
.name = "file",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static QemuOptsList qemu_option_rom_opts = {
|
|
|
|
.name = "option-rom",
|
|
|
|
.implied_opt_name = "romfile",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_option_rom_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "bootindex",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
}, {
|
|
|
|
.name = "romfile",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static QemuOptsList qemu_machine_opts = {
|
|
|
|
.name = "machine",
|
|
|
|
.implied_opt_name = "type",
|
|
|
|
.merge_lists = true,
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head),
|
|
|
|
.desc = {
|
2014-12-16 17:58:05 +01:00
|
|
|
/*
|
|
|
|
* no elements => accept any
|
|
|
|
* sanity checking will happen later
|
|
|
|
* when setting machine properties
|
|
|
|
*/
|
|
|
|
{ }
|
2012-11-26 16:03:42 +01:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static QemuOptsList qemu_boot_opts = {
|
|
|
|
.name = "boot-opts",
|
2013-06-14 13:15:01 +02:00
|
|
|
.implied_opt_name = "order",
|
|
|
|
.merge_lists = true,
|
2012-11-26 16:03:42 +01: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 13:15:01 +02:00
|
|
|
.type = QEMU_OPT_BOOL,
|
2012-11-26 16:03:42 +01:00
|
|
|
}, {
|
|
|
|
.name = "splash",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
}, {
|
|
|
|
.name = "splash-time",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
}, {
|
|
|
|
.name = "reboot-timeout",
|
|
|
|
.type = QEMU_OPT_STRING,
|
2013-03-19 07:23:27 +01:00
|
|
|
}, {
|
|
|
|
.name = "strict",
|
2013-12-09 12:53:15 +01:00
|
|
|
.type = QEMU_OPT_BOOL,
|
2012-11-26 16:03:42 +01: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 18:47:49 +01:00
|
|
|
static QemuOptsList qemu_tpmdev_opts = {
|
|
|
|
.name = "tpmdev",
|
|
|
|
.implied_opt_name = "type",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_tpmdev_opts.head),
|
|
|
|
.desc = {
|
2013-04-22 16:41:39 +02: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 18:47:49 +01:00
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2013-04-19 16:42:06 +02:00
|
|
|
static QemuOptsList qemu_realtime_opts = {
|
|
|
|
.name = "realtime",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_realtime_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "mlock",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2013-07-04 05:02:46 +02:00
|
|
|
static QemuOptsList qemu_msg_opts = {
|
|
|
|
.name = "msg",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_msg_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "timestamp",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2014-01-30 11:20:30 +01: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 11:20:31 +01: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 11:20:30 +01:00
|
|
|
},
|
|
|
|
{ /* End of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2013-11-27 01:27:35 +01: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 15:25:02 +02:00
|
|
|
{
|
|
|
|
.name = "slots",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.name = "maxmem",
|
|
|
|
.type = QEMU_OPT_SIZE,
|
|
|
|
},
|
2013-11-27 01:27:35 +01:00
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2014-07-25 11:56:28 +02: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 11:56:29 +02:00
|
|
|
}, {
|
|
|
|
.name = "align",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
2015-05-29 17:14:05 +02:00
|
|
|
}, {
|
|
|
|
.name = "sleep",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
2014-07-25 11:56:28 +02:00
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2014-12-11 13:07:48 +01:00
|
|
|
static QemuOptsList qemu_semihosting_config_opts = {
|
|
|
|
.name = "semihosting-config",
|
|
|
|
.implied_opt_name = "enable",
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_semihosting_config_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "enable",
|
|
|
|
.type = QEMU_OPT_BOOL,
|
|
|
|
}, {
|
|
|
|
.name = "target",
|
|
|
|
.type = QEMU_OPT_STRING,
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2015-04-29 17:21:53 +02: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,
|
|
|
|
.help = "Sets the name of the file from which\n"
|
|
|
|
"the fw_cfg blob will be loaded",
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2013-07-04 15:09:19 +02:00
|
|
|
/**
|
|
|
|
* Get machine options
|
|
|
|
*
|
|
|
|
* Returns: machine options (never null).
|
|
|
|
*/
|
|
|
|
QemuOpts *qemu_get_machine_opts(void)
|
|
|
|
{
|
2014-03-06 10:39:24 +01:00
|
|
|
return qemu_find_opts_singleton("machine");
|
2013-07-04 15:09:19 +02:00
|
|
|
}
|
|
|
|
|
2012-08-06 10:24:55 +02:00
|
|
|
const char *qemu_get_vm_name(void)
|
|
|
|
{
|
|
|
|
return qemu_name;
|
|
|
|
}
|
|
|
|
|
2011-07-27 12:04:55 +02:00
|
|
|
static void res_free(void)
|
|
|
|
{
|
|
|
|
if (boot_splash_filedata != NULL) {
|
2011-08-21 05:09:37 +02:00
|
|
|
g_free(boot_splash_filedata);
|
2011-07-27 12:04:55 +02:00
|
|
|
boot_splash_filedata = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp)
|
2009-12-08 13:11:41 +01:00
|
|
|
{
|
|
|
|
const char *driver = qemu_opt_get(opts, "driver");
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!driver)
|
|
|
|
return 0;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(default_list); i++) {
|
|
|
|
if (strcmp(default_list[i].driver, driver) != 0)
|
|
|
|
continue;
|
|
|
|
*(default_list[i].flag) = 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-07-29 20:04:45 +02:00
|
|
|
/***********************************************************/
|
|
|
|
/* QEMU state */
|
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
static RunState current_run_state = RUN_STATE_PRELAUNCH;
|
2011-07-29 20:04:45 +02:00
|
|
|
|
2014-06-05 14:53:58 +02:00
|
|
|
/* We use RUN_STATE_MAX but any invalid value will do */
|
|
|
|
static RunState vmstop_requested = RUN_STATE_MAX;
|
|
|
|
static QemuMutex vmstop_lock;
|
|
|
|
|
2011-09-05 21:36:31 +02:00
|
|
|
typedef struct {
|
|
|
|
RunState from;
|
|
|
|
RunState to;
|
|
|
|
} RunStateTransition;
|
|
|
|
|
|
|
|
static const RunStateTransition runstate_transitions_def[] = {
|
|
|
|
/* from -> to */
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_DEBUG, RUN_STATE_RUNNING },
|
2013-12-03 13:00:15 +01:00
|
|
|
{ RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_RUNNING },
|
2012-10-19 16:45:24 +02:00
|
|
|
{ RUN_STATE_INMIGRATE, RUN_STATE_PAUSED },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
|
2011-10-14 16:18:09 +02:00
|
|
|
{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },
|
2011-10-14 16:18:09 +02:00
|
|
|
{ RUN_STATE_IO_ERROR, RUN_STATE_FINISH_MIGRATE },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_PAUSED, RUN_STATE_RUNNING },
|
2011-10-14 16:18:09 +02:00
|
|
|
{ RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
|
2011-10-14 16:18:09 +02:00
|
|
|
{ RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },
|
2011-10-14 16:18:09 +02:00
|
|
|
{ RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE },
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
|
|
|
|
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_DEBUG },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_IO_ERROR },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_PAUSED },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_FINISH_MIGRATE },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_RESTORE_VM },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_SAVE_VM },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
|
2013-04-26 05:24:40 +02:00
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
|
2011-10-14 16:18:09 +02:00
|
|
|
{ RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
2012-04-27 18:33:36 +02:00
|
|
|
{ RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
|
|
|
|
{ RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
|
|
|
|
{ RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
|
|
|
|
{ RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
|
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
|
2011-10-14 16:18:09 +02:00
|
|
|
{ RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
|
2011-09-05 21:36:31 +02:00
|
|
|
|
vl: allow "cont" from panicked state
After reporting the GUEST_PANICKED monitor event, QEMU stops the VM.
The reason for this is that events are edge-triggered, and can be lost if
management dies at the wrong time. Stopping a panicked VM lets management
know of a panic even if it has crashed; management can learn about the
panic when it restarts and queries running QEMU processes. The downside
is of course that the VM will be paused while management is not running,
but that is acceptable if it only happens with explicit "-device pvpanic".
Upon learning of a panic, management (if configured to do so) can pick a
variety of behaviors: leave the VM paused, reset it, destroy it. In
addition to all of these behaviors, it is possible to dump the VM core
from the host.
However, right now, the panicked state is irreversible, and can only be
exited by resetting the machine. This means that any policy decision
is entirely in the hands of the host. In particular there is no way to
use the "reboot on panic" option together with pvpanic.
This patch makes the panicked state reversible (and removes various
workarounds that were there because of the state being irreversible).
With this change, management has a wider set of possible policies: it
can just log the crash and leave policy to the guest, it can leave the
VM paused. In particular, the "log the crash and continue" is implemented
simply by sending a "cont" as soon as management learns about the panic.
Management could also implement the "irreversible paused state" itself.
And again, all such actions can be coupled with dumping the VM core.
Unfortunately we cannot change the behavior of 1.6.0. Thus, even if
it uses "-device pvpanic", management should check for "cont" failures.
If "cont" fails, management can then log that the VM remained paused
and urge the administrator to update QEMU.
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2013-11-04 14:30:47 +01:00
|
|
|
{ RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING },
|
2013-05-20 12:46:20 +02:00
|
|
|
{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
|
2013-04-26 05:24:40 +02:00
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
{ RUN_STATE_MAX, RUN_STATE_MAX },
|
2011-09-05 21:36:31 +02:00
|
|
|
};
|
|
|
|
|
2011-09-30 19:45:27 +02:00
|
|
|
static bool runstate_valid_transitions[RUN_STATE_MAX][RUN_STATE_MAX];
|
|
|
|
|
2011-07-29 20:04:45 +02:00
|
|
|
bool runstate_check(RunState state)
|
|
|
|
{
|
|
|
|
return current_run_state == state;
|
|
|
|
}
|
|
|
|
|
2012-10-28 12:04:47 +01:00
|
|
|
static void runstate_init(void)
|
2011-09-05 21:36:31 +02:00
|
|
|
{
|
|
|
|
const RunStateTransition *p;
|
|
|
|
|
|
|
|
memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions));
|
2011-09-30 19:45:27 +02:00
|
|
|
for (p = &runstate_transitions_def[0]; p->from != RUN_STATE_MAX; p++) {
|
2011-09-05 21:36:31 +02:00
|
|
|
runstate_valid_transitions[p->from][p->to] = true;
|
|
|
|
}
|
2014-06-05 14:53:58 +02:00
|
|
|
|
|
|
|
qemu_mutex_init(&vmstop_lock);
|
2011-09-05 21:36:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* This function will abort() on invalid state transitions */
|
2011-07-29 20:04:45 +02:00
|
|
|
void runstate_set(RunState new_state)
|
|
|
|
{
|
2011-10-13 15:59:07 +02:00
|
|
|
assert(new_state < RUN_STATE_MAX);
|
|
|
|
|
|
|
|
if (!runstate_valid_transitions[current_run_state][new_state]) {
|
|
|
|
fprintf(stderr, "ERROR: invalid runstate transition: '%s' -> '%s'\n",
|
|
|
|
RunState_lookup[current_run_state],
|
|
|
|
RunState_lookup[new_state]);
|
2011-09-05 21:36:31 +02:00
|
|
|
abort();
|
|
|
|
}
|
2013-03-22 09:26:59 +01:00
|
|
|
trace_runstate_set(new_state);
|
2011-07-29 20:04:45 +02:00
|
|
|
current_run_state = new_state;
|
|
|
|
}
|
|
|
|
|
2011-09-12 22:54:20 +02:00
|
|
|
int runstate_is_running(void)
|
2011-08-29 21:02:57 +02:00
|
|
|
{
|
2011-09-12 22:54:20 +02:00
|
|
|
return runstate_check(RUN_STATE_RUNNING);
|
2011-08-29 21:02:57 +02:00
|
|
|
}
|
|
|
|
|
2013-04-26 05:24:40 +02:00
|
|
|
bool runstate_needs_reset(void)
|
|
|
|
{
|
|
|
|
return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
|
vl: allow "cont" from panicked state
After reporting the GUEST_PANICKED monitor event, QEMU stops the VM.
The reason for this is that events are edge-triggered, and can be lost if
management dies at the wrong time. Stopping a panicked VM lets management
know of a panic even if it has crashed; management can learn about the
panic when it restarts and queries running QEMU processes. The downside
is of course that the VM will be paused while management is not running,
but that is acceptable if it only happens with explicit "-device pvpanic".
Upon learning of a panic, management (if configured to do so) can pick a
variety of behaviors: leave the VM paused, reset it, destroy it. In
addition to all of these behaviors, it is possible to dump the VM core
from the host.
However, right now, the panicked state is irreversible, and can only be
exited by resetting the machine. This means that any policy decision
is entirely in the hands of the host. In particular there is no way to
use the "reboot on panic" option together with pvpanic.
This patch makes the panicked state reversible (and removes various
workarounds that were there because of the state being irreversible).
With this change, management has a wider set of possible policies: it
can just log the crash and leave policy to the guest, it can leave the
VM paused. In particular, the "log the crash and continue" is implemented
simply by sending a "cont" as soon as management learns about the panic.
Management could also implement the "irreversible paused state" itself.
And again, all such actions can be coupled with dumping the VM core.
Unfortunately we cannot change the behavior of 1.6.0. Thus, even if
it uses "-device pvpanic", management should check for "cont" failures.
If "cont" fails, management can then log that the VM remained paused
and urge the administrator to update QEMU.
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2013-11-04 14:30:47 +01:00
|
|
|
runstate_check(RUN_STATE_SHUTDOWN);
|
2013-04-26 05:24:40 +02:00
|
|
|
}
|
|
|
|
|
2011-09-12 22:54:20 +02:00
|
|
|
StatusInfo *qmp_query_status(Error **errp)
|
2011-07-29 20:36:43 +02:00
|
|
|
{
|
2011-09-12 22:54:20 +02:00
|
|
|
StatusInfo *info = g_malloc0(sizeof(*info));
|
|
|
|
|
|
|
|
info->running = runstate_is_running();
|
|
|
|
info->singlestep = singlestep;
|
|
|
|
info->status = current_run_state;
|
|
|
|
|
|
|
|
return info;
|
2011-07-29 20:36:43 +02:00
|
|
|
}
|
|
|
|
|
2014-06-05 14:53:58 +02:00
|
|
|
static bool qemu_vmstop_requested(RunState *r)
|
|
|
|
{
|
|
|
|
qemu_mutex_lock(&vmstop_lock);
|
|
|
|
*r = vmstop_requested;
|
|
|
|
vmstop_requested = RUN_STATE_MAX;
|
|
|
|
qemu_mutex_unlock(&vmstop_lock);
|
|
|
|
return *r < RUN_STATE_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_system_vmstop_request_prepare(void)
|
|
|
|
{
|
|
|
|
qemu_mutex_lock(&vmstop_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_system_vmstop_request(RunState state)
|
|
|
|
{
|
|
|
|
vmstop_requested = state;
|
|
|
|
qemu_mutex_unlock(&vmstop_lock);
|
|
|
|
qemu_notify_event();
|
|
|
|
}
|
|
|
|
|
|
|
|
void vm_start(void)
|
|
|
|
{
|
|
|
|
RunState requested;
|
|
|
|
|
|
|
|
qemu_vmstop_requested(&requested);
|
|
|
|
if (runstate_is_running() && requested == RUN_STATE_MAX) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ensure that a STOP/RESUME pair of events is emitted if a
|
|
|
|
* vmstop request was pending. The BLOCK_IO_ERROR event, for
|
|
|
|
* example, according to documentation is always followed by
|
|
|
|
* the STOP event.
|
|
|
|
*/
|
|
|
|
if (runstate_is_running()) {
|
2014-06-18 08:43:37 +02:00
|
|
|
qapi_event_send_stop(&error_abort);
|
2014-06-05 14:53:58 +02:00
|
|
|
} else {
|
|
|
|
cpu_enable_ticks();
|
|
|
|
runstate_set(RUN_STATE_RUNNING);
|
|
|
|
vm_state_notify(1, RUN_STATE_RUNNING);
|
|
|
|
resume_all_vcpus();
|
|
|
|
}
|
|
|
|
|
2014-06-18 08:43:37 +02:00
|
|
|
qapi_event_send_resume(&error_abort);
|
2014-06-05 14:53:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-13 14:05:34 +01:00
|
|
|
/***********************************************************/
|
|
|
|
/* real time host monotonic timer */
|
2006-04-12 23:09:08 +02:00
|
|
|
|
2015-02-27 14:11:02 +01:00
|
|
|
static time_t qemu_time(void)
|
|
|
|
{
|
|
|
|
return qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
|
|
|
|
}
|
|
|
|
|
2008-02-17 12:42:19 +01:00
|
|
|
/***********************************************************/
|
|
|
|
/* host time/date access */
|
|
|
|
void qemu_get_timedate(struct tm *tm, int offset)
|
|
|
|
{
|
2015-02-27 14:11:02 +01:00
|
|
|
time_t ti = qemu_time();
|
2008-02-17 12:42:19 +01:00
|
|
|
|
|
|
|
ti += offset;
|
|
|
|
if (rtc_date_offset == -1) {
|
|
|
|
if (rtc_utc)
|
2013-01-07 23:08:13 +01:00
|
|
|
gmtime_r(&ti, tm);
|
2008-02-17 12:42:19 +01:00
|
|
|
else
|
2013-01-07 23:08:13 +01:00
|
|
|
localtime_r(&ti, tm);
|
2008-02-17 12:42:19 +01:00
|
|
|
} else {
|
|
|
|
ti -= rtc_date_offset;
|
2013-01-07 23:08:13 +01:00
|
|
|
gmtime_r(&ti, tm);
|
2008-02-17 12:42:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int qemu_timedate_diff(struct tm *tm)
|
|
|
|
{
|
|
|
|
time_t seconds;
|
|
|
|
|
|
|
|
if (rtc_date_offset == -1)
|
|
|
|
if (rtc_utc)
|
|
|
|
seconds = mktimegm(tm);
|
2011-11-06 17:00:22 +01:00
|
|
|
else {
|
|
|
|
struct tm tmp = *tm;
|
|
|
|
tmp.tm_isdst = -1; /* use timezone to figure it out */
|
|
|
|
seconds = mktime(&tmp);
|
|
|
|
}
|
2008-02-17 12:42:19 +01:00
|
|
|
else
|
|
|
|
seconds = mktimegm(tm) + rtc_date_offset;
|
|
|
|
|
2015-02-27 14:11:02 +01:00
|
|
|
return seconds - qemu_time();
|
2008-02-17 12:42:19 +01:00
|
|
|
}
|
|
|
|
|
2009-09-15 13:36:04 +02:00
|
|
|
static void configure_rtc_date_offset(const char *startdate, int legacy)
|
|
|
|
{
|
|
|
|
time_t rtc_start_date;
|
|
|
|
struct tm tm;
|
|
|
|
|
|
|
|
if (!strcmp(startdate, "now") && legacy) {
|
|
|
|
rtc_date_offset = -1;
|
|
|
|
} else {
|
|
|
|
if (sscanf(startdate, "%d-%d-%dT%d:%d:%d",
|
|
|
|
&tm.tm_year,
|
|
|
|
&tm.tm_mon,
|
|
|
|
&tm.tm_mday,
|
|
|
|
&tm.tm_hour,
|
|
|
|
&tm.tm_min,
|
|
|
|
&tm.tm_sec) == 6) {
|
|
|
|
/* OK */
|
|
|
|
} else if (sscanf(startdate, "%d-%d-%d",
|
|
|
|
&tm.tm_year,
|
|
|
|
&tm.tm_mon,
|
|
|
|
&tm.tm_mday) == 3) {
|
|
|
|
tm.tm_hour = 0;
|
|
|
|
tm.tm_min = 0;
|
|
|
|
tm.tm_sec = 0;
|
|
|
|
} else {
|
|
|
|
goto date_fail;
|
|
|
|
}
|
|
|
|
tm.tm_year -= 1900;
|
|
|
|
tm.tm_mon--;
|
|
|
|
rtc_start_date = mktimegm(&tm);
|
|
|
|
if (rtc_start_date == -1) {
|
|
|
|
date_fail:
|
|
|
|
fprintf(stderr, "Invalid date format. Valid formats are:\n"
|
|
|
|
"'2006-06-17T16:01:21' or '2006-06-17'\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2015-02-27 14:11:02 +01:00
|
|
|
rtc_date_offset = qemu_time() - rtc_start_date;
|
2009-09-15 13:36:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void configure_rtc(QemuOpts *opts)
|
|
|
|
{
|
|
|
|
const char *value;
|
|
|
|
|
|
|
|
value = qemu_opt_get(opts, "base");
|
|
|
|
if (value) {
|
|
|
|
if (!strcmp(value, "utc")) {
|
|
|
|
rtc_utc = 1;
|
|
|
|
} else if (!strcmp(value, "localtime")) {
|
|
|
|
rtc_utc = 0;
|
|
|
|
} else {
|
|
|
|
configure_rtc_date_offset(value, 0);
|
|
|
|
}
|
|
|
|
}
|
2009-09-15 13:36:04 +02:00
|
|
|
value = qemu_opt_get(opts, "clock");
|
|
|
|
if (value) {
|
|
|
|
if (!strcmp(value, "host")) {
|
2013-08-21 17:03:04 +02:00
|
|
|
rtc_clock = QEMU_CLOCK_HOST;
|
2012-03-30 12:31:21 +02:00
|
|
|
} else if (!strcmp(value, "rt")) {
|
2013-08-21 17:03:04 +02:00
|
|
|
rtc_clock = QEMU_CLOCK_REALTIME;
|
2009-09-15 13:36:04 +02:00
|
|
|
} else if (!strcmp(value, "vm")) {
|
2013-08-21 17:03:04 +02:00
|
|
|
rtc_clock = QEMU_CLOCK_VIRTUAL;
|
2009-09-15 13:36:04 +02:00
|
|
|
} else {
|
|
|
|
fprintf(stderr, "qemu: invalid option value '%s'\n", value);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
2009-09-15 13:36:04 +02:00
|
|
|
value = qemu_opt_get(opts, "driftfix");
|
|
|
|
if (value) {
|
2010-03-27 22:33:46 +01:00
|
|
|
if (!strcmp(value, "slew")) {
|
2012-01-23 20:15:12 +01:00
|
|
|
static GlobalProperty slew_lost_ticks[] = {
|
|
|
|
{
|
|
|
|
.driver = "mc146818rtc",
|
|
|
|
.property = "lost_tick_policy",
|
|
|
|
.value = "slew",
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
};
|
|
|
|
|
|
|
|
qdev_prop_register_global_list(slew_lost_ticks);
|
2010-03-27 22:33:46 +01:00
|
|
|
} else if (!strcmp(value, "none")) {
|
2012-01-23 20:15:12 +01:00
|
|
|
/* discard is default */
|
2009-09-15 13:36:04 +02:00
|
|
|
} else {
|
|
|
|
fprintf(stderr, "qemu: invalid option value '%s'\n", value);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-09-29 01:19:47 +02:00
|
|
|
/***********************************************************/
|
|
|
|
/* Bluetooth support */
|
|
|
|
static int nb_hcis;
|
|
|
|
static int cur_hci;
|
|
|
|
static struct HCIInfo *hci_table[MAX_NICS];
|
2008-11-09 01:04:26 +01:00
|
|
|
|
2008-09-29 01:19:47 +02:00
|
|
|
struct HCIInfo *qemu_next_hci(void)
|
|
|
|
{
|
|
|
|
if (cur_hci == nb_hcis)
|
|
|
|
return &null_hci;
|
|
|
|
|
|
|
|
return hci_table[cur_hci++];
|
|
|
|
}
|
|
|
|
|
2008-11-09 01:04:26 +01:00
|
|
|
static int bt_hci_parse(const char *str)
|
|
|
|
{
|
|
|
|
struct HCIInfo *hci;
|
2009-10-01 23:12:16 +02:00
|
|
|
bdaddr_t bdaddr;
|
2008-11-09 01:04:26 +01:00
|
|
|
|
|
|
|
if (nb_hcis >= MAX_NICS) {
|
|
|
|
fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
hci = hci_init(str);
|
|
|
|
if (!hci)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
bdaddr.b[0] = 0x52;
|
|
|
|
bdaddr.b[1] = 0x54;
|
|
|
|
bdaddr.b[2] = 0x00;
|
|
|
|
bdaddr.b[3] = 0x12;
|
|
|
|
bdaddr.b[4] = 0x34;
|
|
|
|
bdaddr.b[5] = 0x56 + nb_hcis;
|
|
|
|
hci->bdaddr_set(hci, bdaddr.b);
|
|
|
|
|
|
|
|
hci_table[nb_hcis++] = hci;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void bt_vhci_add(int vlan_id)
|
|
|
|
{
|
|
|
|
struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
|
|
|
|
|
|
|
|
if (!vlan->slave)
|
|
|
|
fprintf(stderr, "qemu: warning: adding a VHCI to "
|
|
|
|
"an empty scatternet %i\n", vlan_id);
|
|
|
|
|
|
|
|
bt_vhci_init(bt_new_hci(vlan));
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct bt_device_s *bt_device_add(const char *opt)
|
|
|
|
{
|
|
|
|
struct bt_scatternet_s *vlan;
|
|
|
|
int vlan_id = 0;
|
|
|
|
char *endp = strstr(opt, ",vlan=");
|
|
|
|
int len = (endp ? endp - opt : strlen(opt)) + 1;
|
|
|
|
char devname[10];
|
|
|
|
|
|
|
|
pstrcpy(devname, MIN(sizeof(devname), len), opt);
|
|
|
|
|
|
|
|
if (endp) {
|
|
|
|
vlan_id = strtol(endp + 6, &endp, 0);
|
|
|
|
if (*endp) {
|
|
|
|
fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vlan = qemu_find_bt_vlan(vlan_id);
|
|
|
|
|
|
|
|
if (!vlan->slave)
|
|
|
|
fprintf(stderr, "qemu: warning: adding a slave device to "
|
|
|
|
"an empty scatternet %i\n", vlan_id);
|
|
|
|
|
|
|
|
if (!strcmp(devname, "keyboard"))
|
|
|
|
return bt_keyboard_init(vlan);
|
|
|
|
|
|
|
|
fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bt_parse(const char *opt)
|
|
|
|
{
|
|
|
|
const char *endp, *p;
|
|
|
|
int vlan;
|
|
|
|
|
|
|
|
if (strstart(opt, "hci", &endp)) {
|
|
|
|
if (!*endp || *endp == ',') {
|
|
|
|
if (*endp)
|
|
|
|
if (!strstart(endp, ",vlan=", 0))
|
|
|
|
opt = endp + 1;
|
|
|
|
|
|
|
|
return bt_hci_parse(opt);
|
|
|
|
}
|
|
|
|
} else if (strstart(opt, "vhci", &endp)) {
|
|
|
|
if (!*endp || *endp == ',') {
|
|
|
|
if (*endp) {
|
|
|
|
if (strstart(endp, ",vlan=", &p)) {
|
|
|
|
vlan = strtol(p, (char **) &endp, 0);
|
|
|
|
if (*endp) {
|
|
|
|
fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
vlan = 0;
|
|
|
|
|
|
|
|
bt_vhci_add(vlan);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} else if (strstart(opt, "device:", &endp))
|
|
|
|
return !bt_device_add(endp);
|
|
|
|
|
|
|
|
fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp)
|
2012-08-14 23:44:08 +02:00
|
|
|
{
|
|
|
|
/* FIXME: change this to true for 1.3 */
|
|
|
|
if (qemu_opt_get_bool(opts, "enable", false)) {
|
|
|
|
#ifdef CONFIG_SECCOMP
|
|
|
|
if (seccomp_start() < 0) {
|
|
|
|
qerror_report(ERROR_CLASS_GENERIC_ERROR,
|
|
|
|
"failed to install seccomp syscall filter in the kernel");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
qerror_report(ERROR_CLASS_GENERIC_ERROR,
|
|
|
|
"sandboxing request but seccomp is not compiled into this build");
|
|
|
|
return -1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
static int parse_name(void *opaque, QemuOpts *opts, Error **errp)
|
2014-01-30 11:20:30 +01:00
|
|
|
{
|
|
|
|
const char *proc_name;
|
|
|
|
|
2014-01-30 11:20:31 +01:00
|
|
|
if (qemu_opt_get(opts, "debug-threads")) {
|
|
|
|
qemu_thread_naming(qemu_opt_get_bool(opts, "debug-threads", false));
|
|
|
|
}
|
2014-01-30 11:20:30 +01: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 13:15:55 +02:00
|
|
|
|
|
|
|
return 0;
|
2014-01-30 11:20:30 +01:00
|
|
|
}
|
|
|
|
|
2015-01-06 14:29:12 +01:00
|
|
|
bool defaults_enabled(void)
|
|
|
|
{
|
|
|
|
return has_defaults;
|
|
|
|
}
|
|
|
|
|
2015-01-06 14:29:14 +01:00
|
|
|
bool usb_enabled(void)
|
2012-09-02 21:25:28 +02:00
|
|
|
{
|
2015-01-06 14:29:14 +01:00
|
|
|
return machine_usb(current_machine);
|
2012-09-02 21:25:28 +02:00
|
|
|
}
|
|
|
|
|
2012-10-18 21:19:34 +02:00
|
|
|
#ifndef _WIN32
|
2015-03-13 13:35:14 +01:00
|
|
|
static int parse_add_fd(void *opaque, QemuOpts *opts, Error **errp)
|
2012-10-18 21:19:34 +02:00
|
|
|
{
|
|
|
|
int fd, dupfd, flags;
|
|
|
|
int64_t fdset_id;
|
|
|
|
const char *fd_opaque = NULL;
|
2015-03-15 10:16:28 +01:00
|
|
|
AddfdInfo *fdinfo;
|
2012-10-18 21:19:34 +02: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) {
|
|
|
|
qerror_report(ERROR_CLASS_GENERIC_ERROR,
|
|
|
|
"fd option is required and must be non-negative");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fd <= STDERR_FILENO) {
|
|
|
|
qerror_report(ERROR_CLASS_GENERIC_ERROR,
|
|
|
|
"fd cannot be a standard I/O stream");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* All fds inherited across exec() necessarily have FD_CLOEXEC
|
|
|
|
* clear, while qemu sets FD_CLOEXEC on all other fds used internally.
|
|
|
|
*/
|
|
|
|
flags = fcntl(fd, F_GETFD);
|
|
|
|
if (flags == -1 || (flags & FD_CLOEXEC)) {
|
|
|
|
qerror_report(ERROR_CLASS_GENERIC_ERROR,
|
|
|
|
"fd is not valid or already in use");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fdset_id < 0) {
|
|
|
|
qerror_report(ERROR_CLASS_GENERIC_ERROR,
|
|
|
|
"set option is required and must be non-negative");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef F_DUPFD_CLOEXEC
|
|
|
|
dupfd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
|
|
|
|
#else
|
|
|
|
dupfd = dup(fd);
|
|
|
|
if (dupfd != -1) {
|
|
|
|
qemu_set_cloexec(dupfd);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (dupfd == -1) {
|
|
|
|
qerror_report(ERROR_CLASS_GENERIC_ERROR,
|
|
|
|
"Error duplicating fd: %s", strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add the duplicate fd, and optionally the opaque string, to the fd set */
|
2015-03-15 10:16:28 +01:00
|
|
|
fdinfo = monitor_fdset_add_fd(dupfd, true, fdset_id, !!fd_opaque, fd_opaque,
|
|
|
|
&error_abort);
|
|
|
|
g_free(fdinfo);
|
2012-10-18 21:19:34 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
static int cleanup_add_fd(void *opaque, QemuOpts *opts, Error **errp)
|
2012-10-18 21:19:34 +02:00
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
fd = qemu_opt_get_number(opts, "fd", -1);
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-09-29 01:19:47 +02:00
|
|
|
/***********************************************************/
|
|
|
|
/* QEMU Block devices */
|
|
|
|
|
2011-01-28 11:21:41 +01: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 05:51:10 +01:00
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
static int drive_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
2009-07-22 16:43:04 +02:00
|
|
|
{
|
2012-11-20 15:30:34 +01:00
|
|
|
BlockInterfaceType *block_default_type = opaque;
|
2009-07-22 16:43:04 +02:00
|
|
|
|
2014-06-06 14:50:58 +02:00
|
|
|
return drive_new(opts, *block_default_type) == NULL;
|
2009-07-22 16:43:04 +02:00
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
static int drive_enable_snapshot(void *opaque, QemuOpts *opts, Error **errp)
|
2009-07-22 16:43:04 +02:00
|
|
|
{
|
2014-08-11 15:00:57 +02:00
|
|
|
if (qemu_opt_get(opts, "snapshot") == NULL) {
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(opts, "snapshot", "on", &error_abort);
|
2009-07-22 16:43:04 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-11-22 21:02:55 +01: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 11:21:45 +01:00
|
|
|
{
|
|
|
|
QemuOpts *opts;
|
2014-10-01 20:19:24 +02: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 11:21:45 +01:00
|
|
|
|
|
|
|
if (!enable || drive_get_by_index(type, index)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
opts = drive_add(type, index, NULL, optstr);
|
|
|
|
if (snapshot) {
|
2015-03-13 13:35:14 +01: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 11:21:45 +01:00
|
|
|
}
|
2014-10-01 20:19:24 +02:00
|
|
|
|
|
|
|
dinfo = drive_new(opts, type);
|
|
|
|
if (!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 11:21:45 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
2014-10-01 20:19:24 +02: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 11:21:45 +01:00
|
|
|
}
|
|
|
|
|
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 13:06:52 +02:00
|
|
|
static QemuOptsList qemu_smp_opts = {
|
|
|
|
.name = "smp-opts",
|
|
|
|
.implied_opt_name = "cpus",
|
|
|
|
.merge_lists = true,
|
|
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_smp_opts.head),
|
|
|
|
.desc = {
|
|
|
|
{
|
|
|
|
.name = "cpus",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
}, {
|
|
|
|
.name = "sockets",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
}, {
|
|
|
|
.name = "cores",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
}, {
|
|
|
|
.name = "threads",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
}, {
|
|
|
|
.name = "maxcpus",
|
|
|
|
.type = QEMU_OPT_NUMBER,
|
|
|
|
},
|
|
|
|
{ /*End of list */ }
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static void smp_parse(QemuOpts *opts)
|
extend -smp parsing to include cores= and threads= options
For injecting multi-core and multi-threading CPU topology into guests
extend the -smp syntax to accommodate cores and threads specification.
Syntax: -smp smp_value[,cores=nr_cores][,threads=nr_threads]\
[,socket=nr_sockets][,maxcpus=max_cpus]
smp_value is the legacy value specifying the total number of vCPUs for
the guest. If you specify one of cores, threads or sockets this value
can be omitted. Missing values will be computed to fulfill:
smp_value = nr_cores * nr_threads * nr_sockets
where it will favour sockets over cores over threads (to mimic the
current behavior, which will only inject multiple sockets.)
So -smp 4,threads=2 will inject two sockets with 2 threads each,
-smp cores=4 is an abbreviation for -smp 4,cores=4,threads=1,sockets=1.
If max_cpus (the number of hotpluggable CPUs) is omitted, it will
be set to smp_value.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-08-19 15:42:40 +02:00
|
|
|
{
|
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 13:06:52 +02:00
|
|
|
if (opts) {
|
extend -smp parsing to include cores= and threads= options
For injecting multi-core and multi-threading CPU topology into guests
extend the -smp syntax to accommodate cores and threads specification.
Syntax: -smp smp_value[,cores=nr_cores][,threads=nr_threads]\
[,socket=nr_sockets][,maxcpus=max_cpus]
smp_value is the legacy value specifying the total number of vCPUs for
the guest. If you specify one of cores, threads or sockets this value
can be omitted. Missing values will be computed to fulfill:
smp_value = nr_cores * nr_threads * nr_sockets
where it will favour sockets over cores over threads (to mimic the
current behavior, which will only inject multiple sockets.)
So -smp 4,threads=2 will inject two sockets with 2 threads each,
-smp cores=4 is an abbreviation for -smp 4,cores=4,threads=1,sockets=1.
If max_cpus (the number of hotpluggable CPUs) is omitted, it will
be set to smp_value.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-08-19 15:42:40 +02:00
|
|
|
|
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 13:06:52 +02:00
|
|
|
unsigned cpus = qemu_opt_get_number(opts, "cpus", 0);
|
|
|
|
unsigned sockets = qemu_opt_get_number(opts, "sockets", 0);
|
|
|
|
unsigned cores = qemu_opt_get_number(opts, "cores", 0);
|
|
|
|
unsigned threads = qemu_opt_get_number(opts, "threads", 0);
|
|
|
|
|
|
|
|
/* compute missing values, prefer sockets over cores over threads */
|
|
|
|
if (cpus == 0 || sockets == 0) {
|
|
|
|
sockets = sockets > 0 ? sockets : 1;
|
|
|
|
cores = cores > 0 ? cores : 1;
|
extend -smp parsing to include cores= and threads= options
For injecting multi-core and multi-threading CPU topology into guests
extend the -smp syntax to accommodate cores and threads specification.
Syntax: -smp smp_value[,cores=nr_cores][,threads=nr_threads]\
[,socket=nr_sockets][,maxcpus=max_cpus]
smp_value is the legacy value specifying the total number of vCPUs for
the guest. If you specify one of cores, threads or sockets this value
can be omitted. Missing values will be computed to fulfill:
smp_value = nr_cores * nr_threads * nr_sockets
where it will favour sockets over cores over threads (to mimic the
current behavior, which will only inject multiple sockets.)
So -smp 4,threads=2 will inject two sockets with 2 threads each,
-smp cores=4 is an abbreviation for -smp 4,cores=4,threads=1,sockets=1.
If max_cpus (the number of hotpluggable CPUs) is omitted, it will
be set to smp_value.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-08-19 15:42:40 +02:00
|
|
|
threads = threads > 0 ? threads : 1;
|
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 13:06:52 +02:00
|
|
|
if (cpus == 0) {
|
|
|
|
cpus = cores * threads * sockets;
|
|
|
|
}
|
2014-12-19 03:59:45 +01:00
|
|
|
} else if (cores == 0) {
|
|
|
|
threads = threads > 0 ? threads : 1;
|
|
|
|
cores = cpus / (sockets * threads);
|
2014-12-19 03:59:47 +01:00
|
|
|
} else if (threads == 0) {
|
2014-12-19 03:59:45 +01:00
|
|
|
threads = cpus / (cores * sockets);
|
2014-12-19 03:59:47 +01:00
|
|
|
} else if (sockets * cores * threads < cpus) {
|
|
|
|
fprintf(stderr, "cpu topology: error: "
|
|
|
|
"sockets (%u) * cores (%u) * threads (%u) < "
|
|
|
|
"smp_cpus (%u)\n",
|
|
|
|
sockets, cores, threads, cpus);
|
|
|
|
exit(1);
|
extend -smp parsing to include cores= and threads= options
For injecting multi-core and multi-threading CPU topology into guests
extend the -smp syntax to accommodate cores and threads specification.
Syntax: -smp smp_value[,cores=nr_cores][,threads=nr_threads]\
[,socket=nr_sockets][,maxcpus=max_cpus]
smp_value is the legacy value specifying the total number of vCPUs for
the guest. If you specify one of cores, threads or sockets this value
can be omitted. Missing values will be computed to fulfill:
smp_value = nr_cores * nr_threads * nr_sockets
where it will favour sockets over cores over threads (to mimic the
current behavior, which will only inject multiple sockets.)
So -smp 4,threads=2 will inject two sockets with 2 threads each,
-smp cores=4 is an abbreviation for -smp 4,cores=4,threads=1,sockets=1.
If max_cpus (the number of hotpluggable CPUs) is omitted, it will
be set to smp_value.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-08-19 15:42:40 +02:00
|
|
|
}
|
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 13:06:52 +02:00
|
|
|
|
|
|
|
max_cpus = qemu_opt_get_number(opts, "maxcpus", 0);
|
|
|
|
|
|
|
|
smp_cpus = cpus;
|
|
|
|
smp_cores = cores > 0 ? cores : 1;
|
|
|
|
smp_threads = threads > 0 ? threads : 1;
|
|
|
|
|
extend -smp parsing to include cores= and threads= options
For injecting multi-core and multi-threading CPU topology into guests
extend the -smp syntax to accommodate cores and threads specification.
Syntax: -smp smp_value[,cores=nr_cores][,threads=nr_threads]\
[,socket=nr_sockets][,maxcpus=max_cpus]
smp_value is the legacy value specifying the total number of vCPUs for
the guest. If you specify one of cores, threads or sockets this value
can be omitted. Missing values will be computed to fulfill:
smp_value = nr_cores * nr_threads * nr_sockets
where it will favour sockets over cores over threads (to mimic the
current behavior, which will only inject multiple sockets.)
So -smp 4,threads=2 will inject two sockets with 2 threads each,
-smp cores=4 is an abbreviation for -smp 4,cores=4,threads=1,sockets=1.
If max_cpus (the number of hotpluggable CPUs) is omitted, it will
be set to smp_value.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-08-19 15:42:40 +02:00
|
|
|
}
|
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 13:06:52 +02:00
|
|
|
|
|
|
|
if (max_cpus == 0) {
|
extend -smp parsing to include cores= and threads= options
For injecting multi-core and multi-threading CPU topology into guests
extend the -smp syntax to accommodate cores and threads specification.
Syntax: -smp smp_value[,cores=nr_cores][,threads=nr_threads]\
[,socket=nr_sockets][,maxcpus=max_cpus]
smp_value is the legacy value specifying the total number of vCPUs for
the guest. If you specify one of cores, threads or sockets this value
can be omitted. Missing values will be computed to fulfill:
smp_value = nr_cores * nr_threads * nr_sockets
where it will favour sockets over cores over threads (to mimic the
current behavior, which will only inject multiple sockets.)
So -smp 4,threads=2 will inject two sockets with 2 threads each,
-smp cores=4 is an abbreviation for -smp 4,cores=4,threads=1,sockets=1.
If max_cpus (the number of hotpluggable CPUs) is omitted, it will
be set to smp_value.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-08-19 15:42:40 +02:00
|
|
|
max_cpus = smp_cpus;
|
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 13:06:52 +02:00
|
|
|
}
|
|
|
|
|
2014-03-18 20:29:24 +01:00
|
|
|
if (max_cpus > MAX_CPUMASK_BITS) {
|
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 13:06:52 +02:00
|
|
|
fprintf(stderr, "Unsupported number of maxcpus\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (max_cpus < smp_cpus) {
|
|
|
|
fprintf(stderr, "maxcpus must be equal to or greater than smp\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
extend -smp parsing to include cores= and threads= options
For injecting multi-core and multi-threading CPU topology into guests
extend the -smp syntax to accommodate cores and threads specification.
Syntax: -smp smp_value[,cores=nr_cores][,threads=nr_threads]\
[,socket=nr_sockets][,maxcpus=max_cpus]
smp_value is the legacy value specifying the total number of vCPUs for
the guest. If you specify one of cores, threads or sockets this value
can be omitted. Missing values will be computed to fulfill:
smp_value = nr_cores * nr_threads * nr_sockets
where it will favour sockets over cores over threads (to mimic the
current behavior, which will only inject multiple sockets.)
So -smp 4,threads=2 will inject two sockets with 2 threads each,
-smp cores=4 is an abbreviation for -smp 4,cores=4,threads=1,sockets=1.
If max_cpus (the number of hotpluggable CPUs) is omitted, it will
be set to smp_value.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-08-19 15:42:40 +02:00
|
|
|
}
|
|
|
|
|
2014-09-23 12:42:24 +02:00
|
|
|
static void realtime_init(void)
|
2013-04-19 16:42:06 +02:00
|
|
|
{
|
|
|
|
if (enable_mlock) {
|
|
|
|
if (os_mlock() < 0) {
|
|
|
|
fprintf(stderr, "qemu: locking memory failed\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-04 05:02:46 +02:00
|
|
|
|
|
|
|
static void configure_msg(QemuOpts *opts)
|
|
|
|
{
|
|
|
|
enable_timestamp_msg = qemu_opt_get_bool(opts, "timestamp", true);
|
|
|
|
}
|
|
|
|
|
2005-11-06 17:13:29 +01:00
|
|
|
/***********************************************************/
|
|
|
|
/* USB devices */
|
|
|
|
|
2010-05-28 15:38:44 +02:00
|
|
|
static int usb_device_add(const char *devname)
|
2005-11-06 17:13:29 +01:00
|
|
|
{
|
2009-08-31 14:24:00 +02:00
|
|
|
USBDevice *dev = NULL;
|
2013-09-03 11:23:09 +02:00
|
|
|
#ifndef CONFIG_LINUX
|
|
|
|
const char *p;
|
|
|
|
#endif
|
2005-11-06 17:13:29 +01:00
|
|
|
|
2015-01-06 14:29:14 +01:00
|
|
|
if (!usb_enabled()) {
|
2005-11-06 17:13:29 +01:00
|
|
|
return -1;
|
2012-09-02 21:25:28 +02:00
|
|
|
}
|
2005-11-06 17:13:29 +01:00
|
|
|
|
2009-10-26 15:56:45 +01:00
|
|
|
/* drivers with .usbdevice_name entry in USBDeviceInfo */
|
|
|
|
dev = usbdevice_create(devname);
|
|
|
|
if (dev)
|
|
|
|
goto done;
|
|
|
|
|
2009-08-31 14:24:00 +02:00
|
|
|
/* the other ones */
|
2011-06-01 14:41:59 +02:00
|
|
|
#ifndef CONFIG_LINUX
|
|
|
|
/* only the linux version is qdev-ified, usb-bsd still needs this */
|
2005-11-06 17:13:29 +01:00
|
|
|
if (strstart(devname, "host:", &p)) {
|
2012-02-27 15:18:47 +01:00
|
|
|
dev = usb_host_device_open(usb_bus_find(-1), p);
|
2005-11-06 17:13:29 +01:00
|
|
|
}
|
2013-09-03 11:23:09 +02:00
|
|
|
#endif
|
2006-05-21 18:30:15 +02:00
|
|
|
if (!dev)
|
|
|
|
return -1;
|
|
|
|
|
2009-08-31 14:24:00 +02:00
|
|
|
done:
|
2005-11-06 17:13:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-08-21 21:27:48 +02:00
|
|
|
static int usb_device_del(const char *devname)
|
|
|
|
{
|
|
|
|
int bus_num, addr;
|
|
|
|
const char *p;
|
|
|
|
|
2012-11-30 13:02:47 +01:00
|
|
|
if (strstart(devname, "host:", &p)) {
|
|
|
|
return -1;
|
|
|
|
}
|
2008-09-14 03:07:41 +02:00
|
|
|
|
2015-01-06 14:29:14 +01:00
|
|
|
if (!usb_enabled()) {
|
2008-08-21 21:27:48 +02:00
|
|
|
return -1;
|
2012-09-02 21:25:28 +02:00
|
|
|
}
|
2008-08-21 21:27:48 +02:00
|
|
|
|
|
|
|
p = strchr(devname, '.');
|
|
|
|
if (!p)
|
|
|
|
return -1;
|
|
|
|
bus_num = strtoul(devname, NULL, 0);
|
|
|
|
addr = strtoul(p + 1, NULL, 0);
|
|
|
|
|
2009-08-31 14:24:00 +02:00
|
|
|
return usb_device_delete_addr(bus_num, addr);
|
2008-08-21 21:27:48 +02:00
|
|
|
}
|
|
|
|
|
2009-07-15 13:59:26 +02:00
|
|
|
static int usb_parse(const char *cmdline)
|
|
|
|
{
|
2009-12-22 21:30:18 +01:00
|
|
|
int r;
|
2010-05-28 15:38:44 +02:00
|
|
|
r = usb_device_add(cmdline);
|
2009-12-22 21:30:18 +01:00
|
|
|
if (r < 0) {
|
|
|
|
fprintf(stderr, "qemu: could not add USB device '%s'\n", cmdline);
|
|
|
|
}
|
|
|
|
return r;
|
2009-07-15 13:59:26 +02:00
|
|
|
}
|
|
|
|
|
hmp: Name HMP command handler functions hmp_COMMAND()
Some are called do_COMMAND() (old ones, usually), some hmp_COMMAND(),
and sometimes COMMAND pointlessly differs in spelling.
Normalize to hmp_COMMAND(), where COMMAND is exactly the command name
with '-' replaced by '_'.
Exceptions:
* do_device_add() and client_migrate_info() *not* renamed to
hmp_device_add(), hmp_client_migrate_info(), because they're also
QMP handlers. They still need to be converted to QAPI.
* do_memory_dump(), do_physical_memory_dump(), do_ioport_read(),
do_ioport_write() renamed do hmp_* instead of hmp_x(), hmp_xp(),
hmp_i(), hmp_o(), because those names are too cryptic for my taste.
* do_info_help() renamed to hmp_info_help() instead of hmp_info(),
because it only covers help.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-02-06 13:55:43 +01:00
|
|
|
void hmp_usb_add(Monitor *mon, const QDict *qdict)
|
2005-11-06 17:13:29 +01:00
|
|
|
{
|
2009-12-22 21:30:18 +01:00
|
|
|
const char *devname = qdict_get_str(qdict, "devname");
|
2010-05-28 15:38:44 +02:00
|
|
|
if (usb_device_add(devname) < 0) {
|
2010-02-18 17:25:24 +01:00
|
|
|
error_report("could not add USB device '%s'", devname);
|
2009-12-22 21:30:18 +01:00
|
|
|
}
|
2005-11-06 17:13:29 +01:00
|
|
|
}
|
|
|
|
|
hmp: Name HMP command handler functions hmp_COMMAND()
Some are called do_COMMAND() (old ones, usually), some hmp_COMMAND(),
and sometimes COMMAND pointlessly differs in spelling.
Normalize to hmp_COMMAND(), where COMMAND is exactly the command name
with '-' replaced by '_'.
Exceptions:
* do_device_add() and client_migrate_info() *not* renamed to
hmp_device_add(), hmp_client_migrate_info(), because they're also
QMP handlers. They still need to be converted to QAPI.
* do_memory_dump(), do_physical_memory_dump(), do_ioport_read(),
do_ioport_write() renamed do hmp_* instead of hmp_x(), hmp_xp(),
hmp_i(), hmp_o(), because those names are too cryptic for my taste.
* do_info_help() renamed to hmp_info_help() instead of hmp_info(),
because it only covers help.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-02-06 13:55:43 +01:00
|
|
|
void hmp_usb_del(Monitor *mon, const QDict *qdict)
|
2005-11-06 17:13:29 +01:00
|
|
|
{
|
2009-12-22 21:30:18 +01:00
|
|
|
const char *devname = qdict_get_str(qdict, "devname");
|
|
|
|
if (usb_device_del(devname) < 0) {
|
2010-02-18 17:25:24 +01:00
|
|
|
error_report("could not delete USB device '%s'", devname);
|
2009-12-22 21:30:18 +01:00
|
|
|
}
|
2005-11-06 17:13:29 +01:00
|
|
|
}
|
|
|
|
|
2005-06-05 16:49:17 +02:00
|
|
|
/***********************************************************/
|
|
|
|
/* machine registration */
|
|
|
|
|
2014-03-05 18:30:47 +01:00
|
|
|
MachineState *current_machine;
|
2005-06-05 16:49:17 +02:00
|
|
|
|
2015-05-07 07:33:57 +02:00
|
|
|
/*
|
|
|
|
* Transitional class registration/init used for converting from
|
|
|
|
* legacy QEMUMachine to MachineClass.
|
|
|
|
*/
|
|
|
|
static void qemu_machine_class_init(ObjectClass *oc, void *data)
|
2014-03-05 18:30:46 +01:00
|
|
|
{
|
|
|
|
MachineClass *mc = MACHINE_CLASS(oc);
|
2014-04-09 19:34:50 +02:00
|
|
|
QEMUMachine *qm = data;
|
|
|
|
mc->name = qm->name;
|
|
|
|
mc->desc = qm->desc;
|
|
|
|
mc->init = qm->init;
|
|
|
|
mc->kvm_type = qm->kvm_type;
|
|
|
|
mc->block_default_type = qm->block_default_type;
|
|
|
|
mc->max_cpus = qm->max_cpus;
|
|
|
|
mc->no_sdcard = qm->no_sdcard;
|
2014-07-01 16:14:41 +02:00
|
|
|
mc->has_dynamic_sysbus = qm->has_dynamic_sysbus;
|
2014-04-09 19:34:50 +02:00
|
|
|
mc->is_default = qm->is_default;
|
|
|
|
mc->default_machine_opts = qm->default_machine_opts;
|
|
|
|
mc->default_boot_order = qm->default_boot_order;
|
2014-03-05 18:30:46 +01:00
|
|
|
}
|
|
|
|
|
2005-06-05 16:49:17 +02:00
|
|
|
int qemu_register_machine(QEMUMachine *m)
|
|
|
|
{
|
2014-03-19 12:24:27 +01:00
|
|
|
char *name = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL);
|
2014-03-05 18:30:46 +01:00
|
|
|
TypeInfo ti = {
|
2014-03-19 12:24:27 +01:00
|
|
|
.name = name,
|
2014-03-05 18:30:46 +01:00
|
|
|
.parent = TYPE_MACHINE,
|
2015-05-07 07:33:57 +02:00
|
|
|
.class_init = qemu_machine_class_init,
|
2014-03-05 18:30:46 +01:00
|
|
|
.class_data = (void *)m,
|
|
|
|
};
|
|
|
|
|
|
|
|
type_register(&ti);
|
2014-03-19 12:24:27 +01:00
|
|
|
g_free(name);
|
2014-03-05 18:30:46 +01:00
|
|
|
|
2005-06-05 16:49:17 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-03-05 18:30:47 +01:00
|
|
|
static MachineClass *find_machine(const char *name)
|
2005-06-05 16:49:17 +02:00
|
|
|
{
|
2014-03-05 18:30:46 +01:00
|
|
|
GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
|
2014-03-05 18:30:47 +01:00
|
|
|
MachineClass *mc = NULL;
|
2005-06-05 16:49:17 +02:00
|
|
|
|
2014-03-05 18:30:46 +01:00
|
|
|
for (el = machines; el; el = el->next) {
|
2014-03-05 18:30:47 +01:00
|
|
|
MachineClass *temp = el->data;
|
2014-03-05 18:30:46 +01:00
|
|
|
|
2014-04-09 19:34:53 +02:00
|
|
|
if (!strcmp(temp->name, name)) {
|
2014-03-05 18:30:47 +01:00
|
|
|
mc = temp;
|
2014-03-05 18:30:46 +01:00
|
|
|
break;
|
|
|
|
}
|
2014-04-09 19:34:53 +02:00
|
|
|
if (temp->alias &&
|
|
|
|
!strcmp(temp->alias, name)) {
|
2014-03-05 18:30:47 +01:00
|
|
|
mc = temp;
|
2014-03-05 18:30:46 +01:00
|
|
|
break;
|
|
|
|
}
|
2005-06-05 16:49:17 +02:00
|
|
|
}
|
2014-03-05 18:30:46 +01:00
|
|
|
|
|
|
|
g_slist_free(machines);
|
2014-03-05 18:30:47 +01:00
|
|
|
return mc;
|
2005-06-05 16:49:17 +02:00
|
|
|
}
|
|
|
|
|
2014-03-05 18:30:47 +01:00
|
|
|
MachineClass *find_default_machine(void)
|
2009-05-22 03:41:01 +02:00
|
|
|
{
|
2014-03-05 18:30:46 +01:00
|
|
|
GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
|
2014-03-05 18:30:47 +01:00
|
|
|
MachineClass *mc = NULL;
|
2009-05-22 03:41:01 +02:00
|
|
|
|
2014-03-05 18:30:46 +01:00
|
|
|
for (el = machines; el; el = el->next) {
|
2014-03-05 18:30:47 +01:00
|
|
|
MachineClass *temp = el->data;
|
2014-03-05 18:30:46 +01:00
|
|
|
|
2014-04-09 19:34:53 +02:00
|
|
|
if (temp->is_default) {
|
2014-03-05 18:30:47 +01:00
|
|
|
mc = temp;
|
2014-03-05 18:30:46 +01:00
|
|
|
break;
|
2009-05-22 03:41:01 +02:00
|
|
|
}
|
|
|
|
}
|
2014-03-05 18:30:46 +01:00
|
|
|
|
|
|
|
g_slist_free(machines);
|
2014-03-05 18:30:47 +01:00
|
|
|
return mc;
|
2009-05-22 03:41:01 +02:00
|
|
|
}
|
|
|
|
|
2012-08-10 18:04:11 +02:00
|
|
|
MachineInfoList *qmp_query_machines(Error **errp)
|
|
|
|
{
|
2014-03-05 18:30:46 +01:00
|
|
|
GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
|
2012-08-10 18:04:11 +02:00
|
|
|
MachineInfoList *mach_list = NULL;
|
|
|
|
|
2014-03-05 18:30:46 +01:00
|
|
|
for (el = machines; el; el = el->next) {
|
|
|
|
MachineClass *mc = el->data;
|
2012-08-10 18:04:11 +02:00
|
|
|
MachineInfoList *entry;
|
|
|
|
MachineInfo *info;
|
|
|
|
|
|
|
|
info = g_malloc0(sizeof(*info));
|
2014-04-09 19:34:53 +02:00
|
|
|
if (mc->is_default) {
|
2012-08-10 18:04:11 +02:00
|
|
|
info->has_is_default = true;
|
|
|
|
info->is_default = true;
|
|
|
|
}
|
|
|
|
|
2014-04-09 19:34:53 +02:00
|
|
|
if (mc->alias) {
|
2012-08-10 18:04:11 +02:00
|
|
|
info->has_alias = true;
|
2014-04-09 19:34:53 +02:00
|
|
|
info->alias = g_strdup(mc->alias);
|
2012-08-10 18:04:11 +02:00
|
|
|
}
|
|
|
|
|
2014-04-09 19:34:53 +02:00
|
|
|
info->name = g_strdup(mc->name);
|
|
|
|
info->cpu_max = !mc->max_cpus ? 1 : mc->max_cpus;
|
2012-08-10 18:04:11 +02:00
|
|
|
|
|
|
|
entry = g_malloc0(sizeof(*entry));
|
|
|
|
entry->value = info;
|
|
|
|
entry->next = mach_list;
|
|
|
|
mach_list = entry;
|
|
|
|
}
|
|
|
|
|
2014-03-05 18:30:46 +01:00
|
|
|
g_slist_free(machines);
|
2012-08-10 18:04:11 +02:00
|
|
|
return mach_list;
|
|
|
|
}
|
|
|
|
|
2014-12-16 17:58:06 +01:00
|
|
|
static int machine_help_func(QemuOpts *opts, MachineState *machine)
|
|
|
|
{
|
|
|
|
ObjectProperty *prop;
|
|
|
|
|
|
|
|
if (!qemu_opt_has_help_opt(opts)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
QTAILQ_FOREACH(prop, &OBJECT(machine)->properties, node) {
|
|
|
|
if (!prop->set) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
error_printf("%s.%s=%s", MACHINE_GET_CLASS(machine)->name,
|
|
|
|
prop->name, prop->type);
|
|
|
|
if (prop->description) {
|
|
|
|
error_printf(" (%s)\n", prop->description);
|
|
|
|
} else {
|
|
|
|
error_printf("\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2004-03-31 21:00:16 +02:00
|
|
|
/***********************************************************/
|
|
|
|
/* main execution loop */
|
|
|
|
|
2005-11-11 01:00:47 +01:00
|
|
|
struct vm_change_state_entry {
|
|
|
|
VMChangeStateHandler *cb;
|
|
|
|
void *opaque;
|
2009-09-12 09:36:22 +02:00
|
|
|
QLIST_ENTRY (vm_change_state_entry) entries;
|
2005-11-11 01:00:47 +01:00
|
|
|
};
|
|
|
|
|
2009-09-12 09:36:22 +02:00
|
|
|
static QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
|
2005-11-11 01:00:47 +01:00
|
|
|
|
|
|
|
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
|
|
|
|
void *opaque)
|
|
|
|
{
|
|
|
|
VMChangeStateEntry *e;
|
|
|
|
|
2011-08-21 05:09:37 +02:00
|
|
|
e = g_malloc0(sizeof (*e));
|
2005-11-11 01:00:47 +01:00
|
|
|
|
|
|
|
e->cb = cb;
|
|
|
|
e->opaque = opaque;
|
2009-09-12 09:36:22 +02:00
|
|
|
QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
|
2005-11-11 01:00:47 +01:00
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
|
|
|
|
{
|
2009-09-12 09:36:22 +02:00
|
|
|
QLIST_REMOVE (e, entries);
|
2011-08-21 05:09:37 +02:00
|
|
|
g_free (e);
|
2005-11-11 01:00:47 +01:00
|
|
|
}
|
|
|
|
|
2011-07-29 19:26:33 +02:00
|
|
|
void vm_state_notify(int running, RunState state)
|
2005-11-11 01:00:47 +01:00
|
|
|
{
|
2014-09-09 14:12:26 +02:00
|
|
|
VMChangeStateEntry *e, *next;
|
2005-11-11 01:00:47 +01:00
|
|
|
|
2011-07-29 19:26:33 +02:00
|
|
|
trace_vm_state_notify(running, state);
|
2010-11-16 13:20:25 +01:00
|
|
|
|
2014-09-09 14:12:26 +02:00
|
|
|
QLIST_FOREACH_SAFE(e, &vm_change_state_head, entries, next) {
|
2011-07-29 19:26:33 +02:00
|
|
|
e->cb(e->opaque, running, state);
|
2005-11-11 01:00:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-06-20 14:37:32 +02:00
|
|
|
/* reset/shutdown handler */
|
|
|
|
|
|
|
|
typedef struct QEMUResetEntry {
|
2009-09-12 09:36:22 +02:00
|
|
|
QTAILQ_ENTRY(QEMUResetEntry) entry;
|
2004-06-20 14:37:32 +02:00
|
|
|
QEMUResetHandler *func;
|
|
|
|
void *opaque;
|
|
|
|
} QEMUResetEntry;
|
|
|
|
|
2009-09-12 09:36:22 +02:00
|
|
|
static QTAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers =
|
|
|
|
QTAILQ_HEAD_INITIALIZER(reset_handlers);
|
2004-06-20 14:37:32 +02:00
|
|
|
static int reset_requested;
|
2011-03-15 12:56:04 +01:00
|
|
|
static int shutdown_requested, shutdown_signal = -1;
|
|
|
|
static pid_t shutdown_pid;
|
2005-07-02 16:31:34 +02:00
|
|
|
static int powerdown_requested;
|
2011-02-07 12:19:16 +01:00
|
|
|
static int debug_requested;
|
2012-02-23 13:45:19 +01:00
|
|
|
static int suspend_requested;
|
2013-09-25 18:38:29 +02:00
|
|
|
static WakeupReason wakeup_reason;
|
2012-09-05 23:06:21 +02:00
|
|
|
static NotifierList powerdown_notifiers =
|
|
|
|
NOTIFIER_LIST_INITIALIZER(powerdown_notifiers);
|
2012-02-23 13:45:19 +01:00
|
|
|
static NotifierList suspend_notifiers =
|
|
|
|
NOTIFIER_LIST_INITIALIZER(suspend_notifiers);
|
|
|
|
static NotifierList wakeup_notifiers =
|
|
|
|
NOTIFIER_LIST_INITIALIZER(wakeup_notifiers);
|
2013-09-25 18:38:29 +02:00
|
|
|
static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE);
|
2004-06-20 14:37:32 +02:00
|
|
|
|
2010-07-22 16:52:48 +02:00
|
|
|
int qemu_shutdown_requested_get(void)
|
|
|
|
{
|
|
|
|
return shutdown_requested;
|
|
|
|
}
|
|
|
|
|
|
|
|
int qemu_reset_requested_get(void)
|
|
|
|
{
|
|
|
|
return reset_requested;
|
|
|
|
}
|
|
|
|
|
2012-10-28 12:04:47 +01:00
|
|
|
static int qemu_shutdown_requested(void)
|
2008-03-18 07:53:05 +01:00
|
|
|
{
|
2014-10-27 15:05:10 +01:00
|
|
|
return atomic_xchg(&shutdown_requested, 0);
|
2008-03-18 07:53:05 +01:00
|
|
|
}
|
|
|
|
|
2012-10-28 12:04:47 +01:00
|
|
|
static void qemu_kill_report(void)
|
2011-03-15 12:56:04 +01:00
|
|
|
{
|
2014-02-04 19:04:21 +01:00
|
|
|
if (!qtest_driver() && shutdown_signal != -1) {
|
2011-03-30 23:03:38 +02:00
|
|
|
fprintf(stderr, "qemu: terminating on signal %d", shutdown_signal);
|
|
|
|
if (shutdown_pid == 0) {
|
|
|
|
/* This happens for eg ^C at the terminal, so it's worth
|
|
|
|
* avoiding printing an odd message in that case.
|
|
|
|
*/
|
|
|
|
fputc('\n', stderr);
|
|
|
|
} else {
|
2011-06-02 19:58:06 +02:00
|
|
|
fprintf(stderr, " from pid " FMT_pid "\n", shutdown_pid);
|
2011-03-30 23:03:38 +02:00
|
|
|
}
|
2011-03-15 12:56:04 +01:00
|
|
|
shutdown_signal = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-28 12:04:47 +01:00
|
|
|
static int qemu_reset_requested(void)
|
2008-03-18 07:53:05 +01:00
|
|
|
{
|
|
|
|
int r = reset_requested;
|
|
|
|
reset_requested = 0;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2012-02-23 13:45:19 +01:00
|
|
|
static int qemu_suspend_requested(void)
|
|
|
|
{
|
|
|
|
int r = suspend_requested;
|
|
|
|
suspend_requested = 0;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2013-09-25 18:38:29 +02:00
|
|
|
static WakeupReason qemu_wakeup_requested(void)
|
2012-08-08 22:29:17 +02:00
|
|
|
{
|
2013-09-25 18:38:29 +02:00
|
|
|
return wakeup_reason;
|
2012-08-08 22:29:17 +02:00
|
|
|
}
|
|
|
|
|
2012-10-28 12:04:47 +01:00
|
|
|
static int qemu_powerdown_requested(void)
|
2008-03-18 07:53:05 +01:00
|
|
|
{
|
|
|
|
int r = powerdown_requested;
|
|
|
|
powerdown_requested = 0;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2009-04-24 20:03:54 +02:00
|
|
|
static int qemu_debug_requested(void)
|
|
|
|
{
|
|
|
|
int r = debug_requested;
|
|
|
|
debug_requested = 0;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2009-06-27 09:25:07 +02:00
|
|
|
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
|
2004-06-20 14:37:32 +02:00
|
|
|
{
|
2011-08-21 05:09:37 +02:00
|
|
|
QEMUResetEntry *re = g_malloc0(sizeof(QEMUResetEntry));
|
2004-06-20 14:37:32 +02:00
|
|
|
|
|
|
|
re->func = func;
|
|
|
|
re->opaque = opaque;
|
2009-09-12 09:36:22 +02:00
|
|
|
QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
|
2004-06-20 14:37:32 +02:00
|
|
|
}
|
|
|
|
|
2009-07-02 00:19:02 +02:00
|
|
|
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
|
2004-06-20 14:37:32 +02:00
|
|
|
{
|
|
|
|
QEMUResetEntry *re;
|
|
|
|
|
2009-09-12 09:36:22 +02:00
|
|
|
QTAILQ_FOREACH(re, &reset_handlers, entry) {
|
2009-07-02 00:19:02 +02:00
|
|
|
if (re->func == func && re->opaque == opaque) {
|
2009-09-12 09:36:22 +02:00
|
|
|
QTAILQ_REMOVE(&reset_handlers, re, entry);
|
2011-08-21 05:09:37 +02:00
|
|
|
g_free(re);
|
2009-07-02 00:19:02 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-07 08:41:51 +02:00
|
|
|
void qemu_devices_reset(void)
|
2009-07-02 00:19:02 +02:00
|
|
|
{
|
|
|
|
QEMUResetEntry *re, *nre;
|
|
|
|
|
|
|
|
/* reset all devices */
|
2009-09-12 09:36:22 +02:00
|
|
|
QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
|
2004-06-20 14:37:32 +02:00
|
|
|
re->func(re->opaque);
|
|
|
|
}
|
2012-08-07 08:41:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_system_reset(bool report)
|
|
|
|
{
|
2014-03-05 18:30:47 +01:00
|
|
|
MachineClass *mc;
|
|
|
|
|
|
|
|
mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
|
|
|
|
|
2014-04-09 19:34:53 +02:00
|
|
|
if (mc && mc->reset) {
|
|
|
|
mc->reset();
|
2012-08-07 08:41:51 +02:00
|
|
|
} else {
|
|
|
|
qemu_devices_reset();
|
|
|
|
}
|
2011-06-14 18:29:43 +02:00
|
|
|
if (report) {
|
2014-06-18 08:43:35 +02:00
|
|
|
qapi_event_send_reset(&error_abort);
|
2011-06-14 18:29:43 +02:00
|
|
|
}
|
2010-03-01 19:10:30 +01:00
|
|
|
cpu_synchronize_all_post_reset();
|
2004-06-20 14:37:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_system_reset_request(void)
|
|
|
|
{
|
2006-10-02 21:44:22 +02:00
|
|
|
if (no_reboot) {
|
|
|
|
shutdown_requested = 1;
|
|
|
|
} else {
|
|
|
|
reset_requested = 1;
|
|
|
|
}
|
2011-02-01 22:15:43 +01:00
|
|
|
cpu_stop_current();
|
2009-04-24 20:03:11 +02:00
|
|
|
qemu_notify_event();
|
2004-06-20 14:37:32 +02:00
|
|
|
}
|
|
|
|
|
2012-02-23 13:45:19 +01:00
|
|
|
static void qemu_system_suspend(void)
|
|
|
|
{
|
|
|
|
pause_all_vcpus();
|
|
|
|
notifier_list_notify(&suspend_notifiers, NULL);
|
2012-04-27 18:33:36 +02:00
|
|
|
runstate_set(RUN_STATE_SUSPENDED);
|
2014-06-18 08:43:38 +02:00
|
|
|
qapi_event_send_suspend(&error_abort);
|
2012-02-23 13:45:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_system_suspend_request(void)
|
|
|
|
{
|
2012-04-27 19:31:12 +02:00
|
|
|
if (runstate_check(RUN_STATE_SUSPENDED)) {
|
2012-02-23 13:45:19 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
suspend_requested = 1;
|
|
|
|
cpu_stop_current();
|
|
|
|
qemu_notify_event();
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_register_suspend_notifier(Notifier *notifier)
|
|
|
|
{
|
|
|
|
notifier_list_add(&suspend_notifiers, notifier);
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_system_wakeup_request(WakeupReason reason)
|
|
|
|
{
|
2014-03-06 21:03:36 +01:00
|
|
|
trace_system_wakeup_request(reason);
|
|
|
|
|
2012-04-27 19:31:12 +02:00
|
|
|
if (!runstate_check(RUN_STATE_SUSPENDED)) {
|
2012-02-23 13:45:19 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!(wakeup_reason_mask & (1 << reason))) {
|
|
|
|
return;
|
|
|
|
}
|
2012-04-27 18:33:36 +02:00
|
|
|
runstate_set(RUN_STATE_RUNNING);
|
2013-09-25 18:38:29 +02:00
|
|
|
wakeup_reason = reason;
|
2012-02-23 13:45:19 +01:00
|
|
|
qemu_notify_event();
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_system_wakeup_enable(WakeupReason reason, bool enabled)
|
|
|
|
{
|
|
|
|
if (enabled) {
|
|
|
|
wakeup_reason_mask |= (1 << reason);
|
|
|
|
} else {
|
|
|
|
wakeup_reason_mask &= ~(1 << reason);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_register_wakeup_notifier(Notifier *notifier)
|
|
|
|
{
|
|
|
|
notifier_list_add(&wakeup_notifiers, notifier);
|
|
|
|
}
|
|
|
|
|
2011-03-15 12:56:04 +01:00
|
|
|
void qemu_system_killed(int signal, pid_t pid)
|
|
|
|
{
|
|
|
|
shutdown_signal = signal;
|
|
|
|
shutdown_pid = pid;
|
2011-09-14 15:38:40 +02:00
|
|
|
no_shutdown = 0;
|
2011-03-15 12:56:04 +01:00
|
|
|
qemu_system_shutdown_request();
|
|
|
|
}
|
|
|
|
|
2004-06-20 14:37:32 +02:00
|
|
|
void qemu_system_shutdown_request(void)
|
|
|
|
{
|
2014-06-21 20:43:03 +02:00
|
|
|
trace_qemu_system_shutdown_request();
|
2004-06-20 14:37:32 +02:00
|
|
|
shutdown_requested = 1;
|
2009-04-24 20:03:11 +02:00
|
|
|
qemu_notify_event();
|
2004-06-20 14:37:32 +02:00
|
|
|
}
|
|
|
|
|
2012-09-05 23:06:25 +02:00
|
|
|
static void qemu_system_powerdown(void)
|
|
|
|
{
|
2014-06-18 08:43:34 +02:00
|
|
|
qapi_event_send_powerdown(&error_abort);
|
2012-09-05 23:06:25 +02:00
|
|
|
notifier_list_notify(&powerdown_notifiers, NULL);
|
|
|
|
}
|
|
|
|
|
2005-07-02 16:31:34 +02:00
|
|
|
void qemu_system_powerdown_request(void)
|
|
|
|
{
|
2014-06-21 20:43:03 +02:00
|
|
|
trace_qemu_system_powerdown_request();
|
2005-07-02 16:31:34 +02:00
|
|
|
powerdown_requested = 1;
|
2009-04-24 20:03:11 +02:00
|
|
|
qemu_notify_event();
|
|
|
|
}
|
|
|
|
|
2012-09-05 23:06:21 +02:00
|
|
|
void qemu_register_powerdown_notifier(Notifier *notifier)
|
|
|
|
{
|
|
|
|
notifier_list_add(&powerdown_notifiers, notifier);
|
|
|
|
}
|
|
|
|
|
2011-02-07 12:19:16 +01:00
|
|
|
void qemu_system_debug_request(void)
|
|
|
|
{
|
|
|
|
debug_requested = 1;
|
2011-02-07 12:19:17 +01:00
|
|
|
qemu_notify_event();
|
2011-02-07 12:19:16 +01:00
|
|
|
}
|
|
|
|
|
2011-09-12 14:03:13 +02:00
|
|
|
static bool main_loop_should_exit(void)
|
|
|
|
{
|
|
|
|
RunState r;
|
|
|
|
if (qemu_debug_requested()) {
|
|
|
|
vm_stop(RUN_STATE_DEBUG);
|
|
|
|
}
|
2012-02-23 13:45:19 +01:00
|
|
|
if (qemu_suspend_requested()) {
|
|
|
|
qemu_system_suspend();
|
|
|
|
}
|
2011-09-12 14:03:13 +02:00
|
|
|
if (qemu_shutdown_requested()) {
|
|
|
|
qemu_kill_report();
|
2014-06-18 08:43:33 +02:00
|
|
|
qapi_event_send_shutdown(&error_abort);
|
2011-09-12 14:03:13 +02:00
|
|
|
if (no_shutdown) {
|
|
|
|
vm_stop(RUN_STATE_SHUTDOWN);
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (qemu_reset_requested()) {
|
|
|
|
pause_all_vcpus();
|
|
|
|
cpu_synchronize_all_states();
|
|
|
|
qemu_system_reset(VMRESET_REPORT);
|
|
|
|
resume_all_vcpus();
|
2013-04-26 05:24:40 +02:00
|
|
|
if (runstate_needs_reset()) {
|
2011-09-12 14:03:13 +02:00
|
|
|
runstate_set(RUN_STATE_PAUSED);
|
|
|
|
}
|
|
|
|
}
|
2012-08-08 22:29:17 +02:00
|
|
|
if (qemu_wakeup_requested()) {
|
|
|
|
pause_all_vcpus();
|
|
|
|
cpu_synchronize_all_states();
|
|
|
|
qemu_system_reset(VMRESET_SILENT);
|
2013-09-25 18:38:29 +02:00
|
|
|
notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
|
|
|
|
wakeup_reason = QEMU_WAKEUP_REASON_NONE;
|
2012-08-08 22:29:17 +02:00
|
|
|
resume_all_vcpus();
|
2014-06-18 08:43:40 +02:00
|
|
|
qapi_event_send_wakeup(&error_abort);
|
2012-08-08 22:29:17 +02:00
|
|
|
}
|
2011-09-12 14:03:13 +02:00
|
|
|
if (qemu_powerdown_requested()) {
|
2012-09-05 23:06:25 +02:00
|
|
|
qemu_system_powerdown();
|
2011-09-12 14:03:13 +02:00
|
|
|
}
|
|
|
|
if (qemu_vmstop_requested(&r)) {
|
|
|
|
vm_stop(r);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-04-24 20:03:33 +02:00
|
|
|
static void main_loop(void)
|
|
|
|
{
|
2011-08-22 17:46:02 +02:00
|
|
|
bool nonblocking;
|
2011-09-12 14:03:13 +02:00
|
|
|
int last_io = 0;
|
2011-02-01 22:15:46 +01:00
|
|
|
#ifdef CONFIG_PROFILER
|
|
|
|
int64_t ti;
|
|
|
|
#endif
|
2011-09-12 14:03:13 +02:00
|
|
|
do {
|
2013-06-03 17:38:43 +02:00
|
|
|
nonblocking = !kvm_enabled() && !xen_enabled() && last_io > 0;
|
2006-02-08 23:46:31 +01:00
|
|
|
#ifdef CONFIG_PROFILER
|
2011-02-01 22:15:47 +01:00
|
|
|
ti = profile_getclock();
|
2006-02-08 23:46:31 +01:00
|
|
|
#endif
|
2011-08-22 17:46:02 +02:00
|
|
|
last_io = main_loop_wait(nonblocking);
|
2006-02-08 23:46:31 +01:00
|
|
|
#ifdef CONFIG_PROFILER
|
2011-02-01 22:15:47 +01:00
|
|
|
dev_time += profile_getclock() - ti;
|
2006-02-08 23:46:31 +01:00
|
|
|
#endif
|
2011-09-12 14:03:13 +02:00
|
|
|
} while (!main_loop_should_exit());
|
2003-06-27 19:34:32 +02:00
|
|
|
}
|
|
|
|
|
2009-04-08 00:58:45 +02:00
|
|
|
static void version(void)
|
|
|
|
{
|
2010-04-28 14:42:01 +02:00
|
|
|
printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
|
2009-04-08 00:58:45 +02:00
|
|
|
}
|
|
|
|
|
2007-06-30 01:26:08 +02:00
|
|
|
static void help(int exitcode)
|
2003-06-24 15:42:40 +02:00
|
|
|
{
|
2011-12-19 07:19:31 +01:00
|
|
|
version();
|
|
|
|
printf("usage: %s [options] [disk_image]\n\n"
|
|
|
|
"'disk_image' is a raw hard disk image for IDE hard disk 0\n\n",
|
|
|
|
error_get_progname());
|
|
|
|
|
2011-12-19 07:19:30 +01:00
|
|
|
#define QEMU_OPTIONS_GENERATE_HELP
|
|
|
|
#include "qemu-options-wrapper.h"
|
2011-12-19 07:19:31 +01:00
|
|
|
|
|
|
|
printf("\nDuring emulation, the following keys are useful:\n"
|
2010-02-08 10:04:56 +01:00
|
|
|
"ctrl-alt-f toggle full screen\n"
|
|
|
|
"ctrl-alt-n switch to virtual console 'n'\n"
|
|
|
|
"ctrl-alt toggle mouse and keyboard grab\n"
|
|
|
|
"\n"
|
2011-12-19 07:19:31 +01:00
|
|
|
"When using -nographic, press 'ctrl-a h' to get some help.\n");
|
|
|
|
|
2007-06-30 01:26:08 +02:00
|
|
|
exit(exitcode);
|
2003-06-24 15:42:40 +02:00
|
|
|
}
|
|
|
|
|
2004-05-14 00:02:20 +02:00
|
|
|
#define HAS_ARG 0x0001
|
|
|
|
|
|
|
|
typedef struct QEMUOption {
|
|
|
|
const char *name;
|
|
|
|
int flags;
|
|
|
|
int index;
|
2010-03-29 21:23:52 +02:00
|
|
|
uint32_t arch_mask;
|
2004-05-14 00:02:20 +02:00
|
|
|
} QEMUOption;
|
|
|
|
|
2008-10-01 21:38:09 +02:00
|
|
|
static const QEMUOption qemu_options[] = {
|
2010-03-29 21:23:52 +02:00
|
|
|
{ "h", 0, QEMU_OPTION_h, QEMU_ARCH_ALL },
|
2011-12-19 07:19:30 +01:00
|
|
|
#define QEMU_OPTIONS_GENERATE_OPTIONS
|
|
|
|
#include "qemu-options-wrapper.h"
|
2004-05-14 00:02:20 +02:00
|
|
|
{ NULL },
|
2003-06-30 12:03:06 +02:00
|
|
|
};
|
2011-09-27 21:15:42 +02:00
|
|
|
|
|
|
|
static bool vga_available(void)
|
|
|
|
{
|
2012-09-08 16:01:20 +02:00
|
|
|
return object_class_by_name("VGA") || object_class_by_name("isa-vga");
|
2011-09-27 21:15:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool cirrus_vga_available(void)
|
|
|
|
{
|
2012-09-08 16:01:20 +02:00
|
|
|
return object_class_by_name("cirrus-vga")
|
|
|
|
|| object_class_by_name("isa-cirrus-vga");
|
2011-09-27 21:15:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool vmware_vga_available(void)
|
|
|
|
{
|
2012-09-08 16:01:20 +02:00
|
|
|
return object_class_by_name("vmware-svga");
|
2011-09-27 21:15:42 +02:00
|
|
|
}
|
|
|
|
|
2012-09-08 12:01:06 +02:00
|
|
|
static bool qxl_vga_available(void)
|
|
|
|
{
|
|
|
|
return object_class_by_name("qxl-vga");
|
|
|
|
}
|
|
|
|
|
2013-10-15 22:03:04 +02:00
|
|
|
static bool tcx_vga_available(void)
|
|
|
|
{
|
|
|
|
return object_class_by_name("SUNW,tcx");
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool cg3_vga_available(void)
|
|
|
|
{
|
|
|
|
return object_class_by_name("cgthree");
|
|
|
|
}
|
|
|
|
|
2014-09-10 14:28:48 +02:00
|
|
|
static bool virtio_vga_available(void)
|
|
|
|
{
|
|
|
|
return object_class_by_name("virtio-vga");
|
|
|
|
}
|
|
|
|
|
2008-09-28 02:42:05 +02:00
|
|
|
static void select_vgahw (const char *p)
|
|
|
|
{
|
|
|
|
const char *opts;
|
|
|
|
|
2014-03-10 15:37:40 +01:00
|
|
|
assert(vga_interface_type == VGA_NONE);
|
2008-09-28 02:42:05 +02:00
|
|
|
if (strstart(p, "std", &opts)) {
|
2011-09-27 21:15:42 +02:00
|
|
|
if (vga_available()) {
|
|
|
|
vga_interface_type = VGA_STD;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Error: standard VGA not available\n");
|
|
|
|
exit(0);
|
|
|
|
}
|
2008-09-28 02:42:05 +02:00
|
|
|
} else if (strstart(p, "cirrus", &opts)) {
|
2011-09-27 21:15:42 +02:00
|
|
|
if (cirrus_vga_available()) {
|
|
|
|
vga_interface_type = VGA_CIRRUS;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Error: Cirrus VGA not available\n");
|
|
|
|
exit(0);
|
|
|
|
}
|
2008-09-28 02:42:05 +02:00
|
|
|
} else if (strstart(p, "vmware", &opts)) {
|
2011-09-27 21:15:42 +02:00
|
|
|
if (vmware_vga_available()) {
|
|
|
|
vga_interface_type = VGA_VMWARE;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Error: VMWare SVGA not available\n");
|
|
|
|
exit(0);
|
|
|
|
}
|
2014-09-10 14:28:48 +02:00
|
|
|
} else if (strstart(p, "virtio", &opts)) {
|
|
|
|
if (virtio_vga_available()) {
|
|
|
|
vga_interface_type = VGA_VIRTIO;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Error: Virtio VGA not available\n");
|
|
|
|
exit(0);
|
|
|
|
}
|
2009-04-22 17:19:53 +02:00
|
|
|
} else if (strstart(p, "xenfb", &opts)) {
|
2009-07-30 12:15:02 +02:00
|
|
|
vga_interface_type = VGA_XENFB;
|
2010-04-27 11:50:11 +02:00
|
|
|
} else if (strstart(p, "qxl", &opts)) {
|
2012-09-08 12:01:06 +02:00
|
|
|
if (qxl_vga_available()) {
|
|
|
|
vga_interface_type = VGA_QXL;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Error: QXL VGA not available\n");
|
|
|
|
exit(0);
|
|
|
|
}
|
2013-10-15 22:03:04 +02:00
|
|
|
} else if (strstart(p, "tcx", &opts)) {
|
|
|
|
if (tcx_vga_available()) {
|
|
|
|
vga_interface_type = VGA_TCX;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Error: TCX framebuffer not available\n");
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
} else if (strstart(p, "cg3", &opts)) {
|
|
|
|
if (cg3_vga_available()) {
|
|
|
|
vga_interface_type = VGA_CG3;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Error: CG3 framebuffer not available\n");
|
|
|
|
exit(0);
|
|
|
|
}
|
2009-04-22 17:19:48 +02:00
|
|
|
} else if (!strstart(p, "none", &opts)) {
|
2008-09-28 02:42:05 +02:00
|
|
|
invalid_vga:
|
|
|
|
fprintf(stderr, "Unknown vga type: %s\n", p);
|
|
|
|
exit(1);
|
|
|
|
}
|
2008-09-28 02:42:12 +02: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 02:42:05 +02:00
|
|
|
}
|
|
|
|
|
2011-03-16 13:33:31 +01:00
|
|
|
static DisplayType select_display(const char *p)
|
|
|
|
{
|
|
|
|
const char *opts;
|
|
|
|
DisplayType display = DT_DEFAULT;
|
|
|
|
|
|
|
|
if (strstart(p, "sdl", &opts)) {
|
|
|
|
#ifdef CONFIG_SDL
|
|
|
|
display = DT_SDL;
|
|
|
|
while (*opts) {
|
|
|
|
const char *nextopt;
|
|
|
|
|
|
|
|
if (strstart(opts, ",frame=", &nextopt)) {
|
|
|
|
opts = nextopt;
|
|
|
|
if (strstart(opts, "on", &nextopt)) {
|
|
|
|
no_frame = 0;
|
|
|
|
} else if (strstart(opts, "off", &nextopt)) {
|
|
|
|
no_frame = 1;
|
|
|
|
} else {
|
2011-03-23 04:40:57 +01:00
|
|
|
goto invalid_sdl_args;
|
2011-03-16 13:33:31 +01:00
|
|
|
}
|
|
|
|
} else if (strstart(opts, ",alt_grab=", &nextopt)) {
|
|
|
|
opts = nextopt;
|
|
|
|
if (strstart(opts, "on", &nextopt)) {
|
|
|
|
alt_grab = 1;
|
|
|
|
} else if (strstart(opts, "off", &nextopt)) {
|
|
|
|
alt_grab = 0;
|
|
|
|
} else {
|
2011-03-23 04:40:57 +01:00
|
|
|
goto invalid_sdl_args;
|
2011-03-16 13:33:31 +01:00
|
|
|
}
|
|
|
|
} else if (strstart(opts, ",ctrl_grab=", &nextopt)) {
|
|
|
|
opts = nextopt;
|
|
|
|
if (strstart(opts, "on", &nextopt)) {
|
|
|
|
ctrl_grab = 1;
|
|
|
|
} else if (strstart(opts, "off", &nextopt)) {
|
|
|
|
ctrl_grab = 0;
|
|
|
|
} else {
|
2011-03-23 04:40:57 +01:00
|
|
|
goto invalid_sdl_args;
|
2011-03-16 13:33:31 +01:00
|
|
|
}
|
|
|
|
} else if (strstart(opts, ",window_close=", &nextopt)) {
|
|
|
|
opts = nextopt;
|
|
|
|
if (strstart(opts, "on", &nextopt)) {
|
|
|
|
no_quit = 0;
|
|
|
|
} else if (strstart(opts, "off", &nextopt)) {
|
|
|
|
no_quit = 1;
|
|
|
|
} else {
|
2011-03-23 04:40:57 +01:00
|
|
|
goto invalid_sdl_args;
|
2011-03-16 13:33:31 +01:00
|
|
|
}
|
2014-11-11 16:54:45 +01:00
|
|
|
} else if (strstart(opts, ",gl=", &nextopt)) {
|
|
|
|
opts = nextopt;
|
|
|
|
if (strstart(opts, "on", &nextopt)) {
|
|
|
|
request_opengl = 1;
|
|
|
|
} else if (strstart(opts, "off", &nextopt)) {
|
|
|
|
request_opengl = 0;
|
|
|
|
} else {
|
|
|
|
goto invalid_sdl_args;
|
|
|
|
}
|
2011-03-16 13:33:31 +01:00
|
|
|
} else {
|
2011-03-23 04:40:57 +01:00
|
|
|
invalid_sdl_args:
|
|
|
|
fprintf(stderr, "Invalid SDL option string: %s\n", p);
|
|
|
|
exit(1);
|
2011-03-16 13:33:31 +01:00
|
|
|
}
|
|
|
|
opts = nextopt;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
fprintf(stderr, "SDL support is disabled\n");
|
|
|
|
exit(1);
|
|
|
|
#endif
|
2011-03-16 13:33:33 +01:00
|
|
|
} else if (strstart(p, "vnc", &opts)) {
|
2011-03-16 13:33:36 +01:00
|
|
|
#ifdef CONFIG_VNC
|
2014-09-16 12:33:03 +02:00
|
|
|
if (*opts == '=') {
|
|
|
|
if (vnc_parse_func(opts+1) == NULL) {
|
|
|
|
exit(1);
|
2011-03-16 13:33:33 +01:00
|
|
|
}
|
2014-09-16 12:33:03 +02:00
|
|
|
} else {
|
2011-03-16 13:33:33 +01:00
|
|
|
fprintf(stderr, "VNC requires a display argument vnc=<display>\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2011-03-16 13:33:36 +01:00
|
|
|
#else
|
|
|
|
fprintf(stderr, "VNC support is disabled\n");
|
|
|
|
exit(1);
|
|
|
|
#endif
|
2011-03-16 13:33:31 +01:00
|
|
|
} else if (strstart(p, "curses", &opts)) {
|
|
|
|
#ifdef CONFIG_CURSES
|
|
|
|
display = DT_CURSES;
|
|
|
|
#else
|
|
|
|
fprintf(stderr, "Curses support is disabled\n");
|
|
|
|
exit(1);
|
2013-02-20 14:43:25 +01:00
|
|
|
#endif
|
|
|
|
} else if (strstart(p, "gtk", &opts)) {
|
|
|
|
#ifdef CONFIG_GTK
|
|
|
|
display = DT_GTK;
|
2014-03-12 08:33:50 +01:00
|
|
|
while (*opts) {
|
|
|
|
const char *nextopt;
|
|
|
|
|
|
|
|
if (strstart(opts, ",grab_on_hover=", &nextopt)) {
|
|
|
|
opts = nextopt;
|
|
|
|
if (strstart(opts, "on", &nextopt)) {
|
|
|
|
grab_on_hover = true;
|
|
|
|
} else if (strstart(opts, "off", &nextopt)) {
|
|
|
|
grab_on_hover = false;
|
|
|
|
} else {
|
|
|
|
goto invalid_gtk_args;
|
|
|
|
}
|
2015-01-20 12:43:28 +01:00
|
|
|
} else if (strstart(opts, ",gl=", &nextopt)) {
|
|
|
|
opts = nextopt;
|
|
|
|
if (strstart(opts, "on", &nextopt)) {
|
|
|
|
request_opengl = 1;
|
|
|
|
} else if (strstart(opts, "off", &nextopt)) {
|
|
|
|
request_opengl = 0;
|
|
|
|
} else {
|
|
|
|
goto invalid_gtk_args;
|
|
|
|
}
|
2014-03-12 08:33:50 +01:00
|
|
|
} else {
|
|
|
|
invalid_gtk_args:
|
|
|
|
fprintf(stderr, "Invalid GTK option string: %s\n", p);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
opts = nextopt;
|
|
|
|
}
|
2013-02-20 14:43:25 +01:00
|
|
|
#else
|
|
|
|
fprintf(stderr, "GTK support is disabled\n");
|
|
|
|
exit(1);
|
2011-03-16 13:33:31 +01:00
|
|
|
#endif
|
2011-03-16 13:33:32 +01:00
|
|
|
} else if (strstart(p, "none", &opts)) {
|
|
|
|
display = DT_NONE;
|
2011-03-16 13:33:31 +01:00
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Unknown display type: %s\n", p);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return display;
|
|
|
|
}
|
|
|
|
|
2009-06-26 19:15:14 +02:00
|
|
|
static int balloon_parse(const char *arg)
|
|
|
|
{
|
2009-08-14 10:34:22 +02:00
|
|
|
QemuOpts *opts;
|
2009-06-26 19:15:14 +02:00
|
|
|
|
2009-08-14 10:34:22 +02:00
|
|
|
if (strcmp(arg, "none") == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strncmp(arg, "virtio", 6)) {
|
|
|
|
if (arg[6] == ',') {
|
|
|
|
/* have params -> parse them */
|
2010-08-20 13:52:01 +02:00
|
|
|
opts = qemu_opts_parse(qemu_find_opts("device"), arg+7, 0);
|
2009-08-14 10:34:22 +02:00
|
|
|
if (!opts)
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
/* create empty opts */
|
2014-01-02 03:49:17 +01:00
|
|
|
opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
|
|
|
|
&error_abort);
|
2009-06-26 19:15:14 +02:00
|
|
|
}
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(opts, "driver", "virtio-balloon", &error_abort);
|
2009-08-14 10:34:22 +02:00
|
|
|
return 0;
|
2009-06-26 19:15:14 +02:00
|
|
|
}
|
2009-08-14 10:34:22 +02:00
|
|
|
|
|
|
|
return -1;
|
2009-06-26 19:15:14 +02:00
|
|
|
}
|
|
|
|
|
2009-05-30 01:52:44 +02:00
|
|
|
char *qemu_find_file(int type, const char *name)
|
|
|
|
{
|
2013-03-08 11:42:24 +01:00
|
|
|
int i;
|
2009-05-30 01:52:44 +02:00
|
|
|
const char *subdir;
|
|
|
|
char *buf;
|
|
|
|
|
2012-05-25 14:07:01 +02:00
|
|
|
/* Try the name as a straight path first */
|
|
|
|
if (access(name, R_OK) == 0) {
|
2013-03-08 11:42:24 +01:00
|
|
|
trace_load_file(name, name);
|
2011-08-21 05:09:37 +02:00
|
|
|
return g_strdup(name);
|
2009-05-30 01:52:44 +02:00
|
|
|
}
|
2013-03-08 11:42:24 +01:00
|
|
|
|
2009-05-30 01:52:44 +02:00
|
|
|
switch (type) {
|
|
|
|
case QEMU_FILE_TYPE_BIOS:
|
|
|
|
subdir = "";
|
|
|
|
break;
|
|
|
|
case QEMU_FILE_TYPE_KEYMAP:
|
|
|
|
subdir = "keymaps/";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
}
|
2013-03-08 11:42:24 +01:00
|
|
|
|
|
|
|
for (i = 0; i < data_dir_idx; i++) {
|
|
|
|
buf = g_strdup_printf("%s/%s%s", data_dir[i], subdir, name);
|
|
|
|
if (access(buf, R_OK) == 0) {
|
|
|
|
trace_load_file(name, buf);
|
|
|
|
return buf;
|
|
|
|
}
|
2011-08-21 05:09:37 +02:00
|
|
|
g_free(buf);
|
2009-05-30 01:52:44 +02:00
|
|
|
}
|
2013-03-08 11:42:24 +01:00
|
|
|
return NULL;
|
2009-05-30 01:52:44 +02:00
|
|
|
}
|
|
|
|
|
2015-04-29 17:21:53 +02:00
|
|
|
static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
|
|
|
|
{
|
|
|
|
gchar *buf;
|
|
|
|
size_t size;
|
|
|
|
const char *name, *file;
|
|
|
|
|
|
|
|
if (opaque == NULL) {
|
|
|
|
error_report("fw_cfg device not available");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
name = qemu_opt_get(opts, "name");
|
|
|
|
file = qemu_opt_get(opts, "file");
|
|
|
|
if (name == NULL || *name == '\0' || file == NULL || *file == '\0') {
|
|
|
|
error_report("invalid argument value");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (strlen(name) > FW_CFG_MAX_FILE_PATH - 1) {
|
|
|
|
error_report("name too long (max. %d char)", FW_CFG_MAX_FILE_PATH - 1);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (strncmp(name, "opt/", 4) != 0) {
|
|
|
|
error_report("WARNING: externally provided fw_cfg item names "
|
|
|
|
"should be prefixed with \"opt/\"!");
|
|
|
|
}
|
|
|
|
if (!g_file_get_contents(file, &buf, &size, NULL)) {
|
|
|
|
error_report("can't load %s", file);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
fw_cfg_add_file((FWCfgState *)opaque, name, buf, size);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
static int device_help_func(void *opaque, QemuOpts *opts, Error **errp)
|
2010-01-29 19:48:57 +01:00
|
|
|
{
|
|
|
|
return qdev_device_help(opts);
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
static int device_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
2009-07-31 12:25:37 +02:00
|
|
|
{
|
|
|
|
DeviceState *dev;
|
|
|
|
|
|
|
|
dev = qdev_device_add(opts);
|
|
|
|
if (!dev)
|
|
|
|
return -1;
|
2013-01-25 14:12:37 +01:00
|
|
|
object_unref(OBJECT(dev));
|
2009-07-31 12:25:37 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
2009-12-08 13:11:36 +01:00
|
|
|
{
|
2012-10-15 09:28:05 +02:00
|
|
|
Error *local_err = NULL;
|
2009-12-08 13:11:36 +01:00
|
|
|
|
2012-10-15 09:28:05 +02:00
|
|
|
qemu_chr_new_from_opts(opts, NULL, &local_err);
|
2014-01-30 15:07:28 +01:00
|
|
|
if (local_err) {
|
2015-02-12 13:55:05 +01:00
|
|
|
error_report_err(local_err);
|
2009-12-08 13:11:36 +01:00
|
|
|
return -1;
|
2012-10-15 09:28:05 +02:00
|
|
|
}
|
2009-12-08 13:11:36 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-06-14 22:34:41 +02:00
|
|
|
#ifdef CONFIG_VIRTFS
|
2015-03-13 13:35:14 +01:00
|
|
|
static int fsdev_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
2010-04-29 14:14:43 +02:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
ret = qemu_fsdev_add(opts);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
2009-12-08 13:11:50 +01:00
|
|
|
{
|
|
|
|
CharDriverState *chr;
|
|
|
|
const char *chardev;
|
|
|
|
const char *mode;
|
|
|
|
int flags;
|
|
|
|
|
|
|
|
mode = qemu_opt_get(opts, "mode");
|
|
|
|
if (mode == NULL) {
|
|
|
|
mode = "readline";
|
|
|
|
}
|
|
|
|
if (strcmp(mode, "readline") == 0) {
|
|
|
|
flags = MONITOR_USE_READLINE;
|
|
|
|
} else if (strcmp(mode, "control") == 0) {
|
|
|
|
flags = MONITOR_USE_CONTROL;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "unknown monitor mode \"%s\"\n", mode);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2010-06-07 16:42:31 +02:00
|
|
|
if (qemu_opt_get_bool(opts, "pretty", 0))
|
|
|
|
flags |= MONITOR_USE_PRETTY;
|
|
|
|
|
2009-12-08 13:11:50 +01:00
|
|
|
if (qemu_opt_get_bool(opts, "default", 0))
|
|
|
|
flags |= MONITOR_IS_DEFAULT;
|
|
|
|
|
|
|
|
chardev = qemu_opt_get(opts, "chardev");
|
|
|
|
chr = qemu_chr_find(chardev);
|
|
|
|
if (chr == NULL) {
|
|
|
|
fprintf(stderr, "chardev \"%s\" not found\n", chardev);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2013-03-27 20:29:40 +01:00
|
|
|
qemu_chr_fe_claim_no_fail(chr);
|
2009-12-08 13:11:50 +01:00
|
|
|
monitor_init(chr, flags);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-11-17 13:31:04 +01:00
|
|
|
static void monitor_parse(const char *optarg, const char *mode, bool pretty)
|
2009-12-08 13:11:50 +01:00
|
|
|
{
|
|
|
|
static int monitor_device_index = 0;
|
2015-01-13 14:19:13 +01:00
|
|
|
Error *local_err = NULL;
|
2009-12-08 13:11:50 +01:00
|
|
|
QemuOpts *opts;
|
|
|
|
const char *p;
|
|
|
|
char label[32];
|
|
|
|
int def = 0;
|
|
|
|
|
|
|
|
if (strstart(optarg, "chardev:", &p)) {
|
|
|
|
snprintf(label, sizeof(label), "%s", p);
|
|
|
|
} else {
|
2010-04-06 16:55:52 +02:00
|
|
|
snprintf(label, sizeof(label), "compat_monitor%d",
|
|
|
|
monitor_device_index);
|
|
|
|
if (monitor_device_index == 0) {
|
2009-12-08 13:11:50 +01:00
|
|
|
def = 1;
|
|
|
|
}
|
|
|
|
opts = qemu_chr_parse_compat(label, optarg);
|
|
|
|
if (!opts) {
|
|
|
|
fprintf(stderr, "parse error: %s\n", optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-13 14:19:13 +01:00
|
|
|
opts = qemu_opts_create(qemu_find_opts("mon"), label, 1, &local_err);
|
2009-12-08 13:11:50 +01:00
|
|
|
if (!opts) {
|
2015-02-12 13:55:05 +01:00
|
|
|
error_report_err(local_err);
|
2009-12-08 13:11:50 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(opts, "mode", mode, &error_abort);
|
|
|
|
qemu_opt_set(opts, "chardev", label, &error_abort);
|
2015-02-12 16:37:44 +01:00
|
|
|
qemu_opt_set_bool(opts, "pretty", pretty, &error_abort);
|
2009-12-08 13:11:50 +01:00
|
|
|
if (def)
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(opts, "default", "on", &error_abort);
|
2009-12-08 13:11:50 +01:00
|
|
|
monitor_device_index++;
|
|
|
|
}
|
|
|
|
|
2009-07-15 13:59:26 +02:00
|
|
|
struct device_config {
|
|
|
|
enum {
|
2009-12-08 13:11:53 +01:00
|
|
|
DEV_USB, /* -usbdevice */
|
|
|
|
DEV_BT, /* -bt */
|
|
|
|
DEV_SERIAL, /* -serial */
|
|
|
|
DEV_PARALLEL, /* -parallel */
|
|
|
|
DEV_VIRTCON, /* -virtioconsole */
|
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-29 22:51:36 +01:00
|
|
|
DEV_DEBUGCON, /* -debugcon */
|
2012-02-07 15:09:13 +01:00
|
|
|
DEV_GDB, /* -gdb, -s */
|
2013-01-24 12:18:52 +01:00
|
|
|
DEV_SCLP, /* s390 sclp */
|
2009-07-15 13:59:26 +02:00
|
|
|
} type;
|
|
|
|
const char *cmdline;
|
2012-02-07 15:09:12 +01:00
|
|
|
Location loc;
|
2009-09-12 09:36:22 +02:00
|
|
|
QTAILQ_ENTRY(device_config) next;
|
2009-07-15 13:59:26 +02:00
|
|
|
};
|
2012-10-28 12:04:47 +01:00
|
|
|
|
|
|
|
static QTAILQ_HEAD(, device_config) device_configs =
|
|
|
|
QTAILQ_HEAD_INITIALIZER(device_configs);
|
2009-07-15 13:59:26 +02:00
|
|
|
|
|
|
|
static void add_device_config(int type, const char *cmdline)
|
|
|
|
{
|
|
|
|
struct device_config *conf;
|
|
|
|
|
2011-08-21 05:09:37 +02:00
|
|
|
conf = g_malloc0(sizeof(*conf));
|
2009-07-15 13:59:26 +02:00
|
|
|
conf->type = type;
|
|
|
|
conf->cmdline = cmdline;
|
2012-02-07 15:09:12 +01:00
|
|
|
loc_save(&conf->loc);
|
2009-09-12 09:36:22 +02:00
|
|
|
QTAILQ_INSERT_TAIL(&device_configs, conf, next);
|
2009-07-15 13:59:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static int foreach_device_config(int type, int (*func)(const char *cmdline))
|
|
|
|
{
|
|
|
|
struct device_config *conf;
|
|
|
|
int rc;
|
|
|
|
|
2009-09-12 09:36:22 +02:00
|
|
|
QTAILQ_FOREACH(conf, &device_configs, next) {
|
2009-07-15 13:59:26 +02:00
|
|
|
if (conf->type != type)
|
|
|
|
continue;
|
2012-02-07 15:09:12 +01:00
|
|
|
loc_push_restore(&conf->loc);
|
2009-07-15 13:59:26 +02:00
|
|
|
rc = func(conf->cmdline);
|
2012-02-07 15:09:12 +01:00
|
|
|
loc_pop(&conf->loc);
|
2014-08-11 15:00:57 +02:00
|
|
|
if (rc) {
|
2009-07-15 13:59:26 +02:00
|
|
|
return rc;
|
2014-08-11 15:00:57 +02:00
|
|
|
}
|
2009-07-15 13:59:26 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-08 13:11:41 +01:00
|
|
|
static int serial_parse(const char *devname)
|
|
|
|
{
|
|
|
|
static int index = 0;
|
|
|
|
char label[32];
|
|
|
|
|
|
|
|
if (strcmp(devname, "none") == 0)
|
|
|
|
return 0;
|
|
|
|
if (index == MAX_SERIAL_PORTS) {
|
|
|
|
fprintf(stderr, "qemu: too many serial ports\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
snprintf(label, sizeof(label), "serial%d", index);
|
2011-08-15 18:17:36 +02:00
|
|
|
serial_hds[index] = qemu_chr_new(label, devname, NULL);
|
2009-12-08 13:11:41 +01:00
|
|
|
if (!serial_hds[index]) {
|
2012-07-09 06:28:30 +02:00
|
|
|
fprintf(stderr, "qemu: could not connect serial device"
|
|
|
|
" to character backend '%s'\n", devname);
|
2009-12-08 13:11:41 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
index++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-08 13:11:42 +01: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) {
|
|
|
|
fprintf(stderr, "qemu: too many parallel ports\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
snprintf(label, sizeof(label), "parallel%d", index);
|
2011-08-15 18:17:36 +02:00
|
|
|
parallel_hds[index] = qemu_chr_new(label, devname, NULL);
|
2009-12-08 13:11:42 +01:00
|
|
|
if (!parallel_hds[index]) {
|
2012-07-09 06:28:30 +02:00
|
|
|
fprintf(stderr, "qemu: could not connect parallel device"
|
|
|
|
" to character backend '%s'\n", devname);
|
2009-12-08 13:11:42 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
index++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-08 13:11:53 +01:00
|
|
|
static int virtcon_parse(const char *devname)
|
|
|
|
{
|
2010-08-20 13:52:01 +02:00
|
|
|
QemuOptsList *device = qemu_find_opts("device");
|
2009-12-08 13:11:53 +01:00
|
|
|
static int index = 0;
|
|
|
|
char label[32];
|
2010-01-21 11:49:23 +01:00
|
|
|
QemuOpts *bus_opts, *dev_opts;
|
2009-12-08 13:11:53 +01:00
|
|
|
|
|
|
|
if (strcmp(devname, "none") == 0)
|
|
|
|
return 0;
|
|
|
|
if (index == MAX_VIRTIO_CONSOLES) {
|
|
|
|
fprintf(stderr, "qemu: too many virtio consoles\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2010-01-21 11:49:23 +01:00
|
|
|
|
2014-01-02 03:49:17 +01:00
|
|
|
bus_opts = qemu_opts_create(device, NULL, 0, &error_abort);
|
2012-02-06 18:07:18 +01:00
|
|
|
if (arch_type == QEMU_ARCH_S390X) {
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(bus_opts, "driver", "virtio-serial-s390", &error_abort);
|
2012-02-06 18:07:18 +01:00
|
|
|
} else {
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(bus_opts, "driver", "virtio-serial-pci", &error_abort);
|
2013-03-21 00:23:13 +01:00
|
|
|
}
|
2010-01-21 11:49:23 +01:00
|
|
|
|
2014-01-02 03:49:17 +01:00
|
|
|
dev_opts = qemu_opts_create(device, NULL, 0, &error_abort);
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(dev_opts, "driver", "virtconsole", &error_abort);
|
2010-01-21 11:49:23 +01:00
|
|
|
|
2009-12-08 13:11:53 +01:00
|
|
|
snprintf(label, sizeof(label), "virtcon%d", index);
|
2011-08-15 18:17:36 +02:00
|
|
|
virtcon_hds[index] = qemu_chr_new(label, devname, NULL);
|
2009-12-08 13:11:53 +01:00
|
|
|
if (!virtcon_hds[index]) {
|
2012-07-09 06:28:30 +02:00
|
|
|
fprintf(stderr, "qemu: could not connect virtio console"
|
|
|
|
" to character backend '%s'\n", devname);
|
2009-12-08 13:11:53 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(dev_opts, "chardev", label, &error_abort);
|
2010-01-21 11:49:23 +01:00
|
|
|
|
2009-12-08 13:11:53 +01:00
|
|
|
index++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-24 12:18:52 +01:00
|
|
|
static int sclp_parse(const char *devname)
|
|
|
|
{
|
|
|
|
QemuOptsList *device = qemu_find_opts("device");
|
|
|
|
static int index = 0;
|
|
|
|
char label[32];
|
|
|
|
QemuOpts *dev_opts;
|
|
|
|
|
|
|
|
if (strcmp(devname, "none") == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (index == MAX_SCLP_CONSOLES) {
|
|
|
|
fprintf(stderr, "qemu: too many sclp consoles\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(arch_type == QEMU_ARCH_S390X);
|
|
|
|
|
|
|
|
dev_opts = qemu_opts_create(device, NULL, 0, NULL);
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(dev_opts, "driver", "sclpconsole", &error_abort);
|
2013-01-24 12:18:52 +01:00
|
|
|
|
|
|
|
snprintf(label, sizeof(label), "sclpcon%d", index);
|
|
|
|
sclp_hds[index] = qemu_chr_new(label, devname, NULL);
|
|
|
|
if (!sclp_hds[index]) {
|
|
|
|
fprintf(stderr, "qemu: could not connect sclp console"
|
|
|
|
" to character backend '%s'\n", devname);
|
|
|
|
return -1;
|
|
|
|
}
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(dev_opts, "chardev", label, &error_abort);
|
2013-01-24 12:18:52 +01:00
|
|
|
|
|
|
|
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-29 22:51:36 +01:00
|
|
|
static int debugcon_parse(const char *devname)
|
2013-03-21 00:23:13 +01: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-29 22:51:36 +01:00
|
|
|
QemuOpts *opts;
|
|
|
|
|
2011-08-15 18:17:36 +02:00
|
|
|
if (!qemu_chr_new("debugcon", devname, 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-29 22:51:36 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
2012-03-20 19:51:57 +01: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-29 22:51:36 +01:00
|
|
|
if (!opts) {
|
|
|
|
fprintf(stderr, "qemu: already have a debugcon device\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2015-02-12 17:52:20 +01: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-29 22:51:36 +01: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-22 22:38:35 +02: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)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static MachineClass *machine_parse(const char *name)
|
2011-07-23 12:38:37 +02:00
|
|
|
{
|
2014-03-05 18:30:47 +01:00
|
|
|
MachineClass *mc = NULL;
|
2014-03-05 18:30:46 +01:00
|
|
|
GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
|
2011-07-23 12:38:37 +02:00
|
|
|
|
|
|
|
if (name) {
|
2014-03-05 18:30:47 +01:00
|
|
|
mc = find_machine(name);
|
2011-07-23 12:38:37 +02:00
|
|
|
}
|
2014-03-05 18:30:47 +01:00
|
|
|
if (mc) {
|
2015-01-28 16:07:17 +01:00
|
|
|
g_slist_free(machines);
|
2014-03-05 18:30:47 +01:00
|
|
|
return mc;
|
2011-07-23 12:38:37 +02:00
|
|
|
}
|
2014-03-14 13:06:54 +01:00
|
|
|
if (name && !is_help_option(name)) {
|
|
|
|
error_report("Unsupported machine type");
|
|
|
|
error_printf("Use -machine help to list supported machines!\n");
|
|
|
|
} else {
|
|
|
|
printf("Supported machines are:\n");
|
well-defined listing order for machine types
Commit 261747f1 ("vl: Use MachineClass instead of global QEMUMachine
list") broke the ordering of the machine types in the user-visible output
of
qemu-system-XXXX -M \?
This occurred because registration was rebased from a manually maintained
linked list to GLib hash tables:
qemu_register_machine()
type_register()
type_register_internal()
type_table_add()
g_hash_table_insert()
and because the listing was rebased accordingly, from the traversal of the
list to the traversal of the hash table (rendered as an ad-hoc list):
machine_parse()
object_class_get_list(TYPE_MACHINE)
object_class_foreach()
g_hash_table_foreach()
The current order is a "random" one, for practical purposes, which is
annoying for users.
Introduce new members QEMUMachine.family and MachineClass.family, allowing
machine types to be "clustered". Introduce a comparator function that
establishes a total ordering between machine types, ordering machine types
in the same family next to each other. In machine_parse(), list the
supported machine types sorted with the comparator function.
The comparator function:
- sorts whole families before standalone machine types,
- sorts whole families between each other in alphabetically increasing
order,
- sorts machine types inside the same family in alphabetically decreasing
order,
- sorts standalone machine types between each other in alphabetically
increasing order.
After this patch, all machine types are considered standalone, and
accordingly, the output is alphabetically ascending. This will be refined
in the following patches.
Effects on the x86_64 output:
Before:
> Supported machines are:
> pc-0.13 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-2.0 Standard PC (i440FX + PIIX, 1996)
> pc-1.0 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-2.1 Standard PC (i440FX + PIIX, 1996)
> pc-q35-1.7 Standard PC (Q35 + ICH9, 2009)
> pc-1.1 Standard PC (i440FX + PIIX, 1996)
> pc-0.14 Standard PC (i440FX + PIIX, 1996)
> pc-q35-2.0 Standard PC (Q35 + ICH9, 2009)
> pc-i440fx-1.4 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.5 Standard PC (i440FX + PIIX, 1996)
> pc-0.15 Standard PC (i440FX + PIIX, 1996)
> pc-q35-1.4 Standard PC (Q35 + ICH9, 2009)
> isapc ISA-only PC
> pc Standard PC (i440FX + PIIX, 1996) (alias of pc-i440fx-2.2)
> pc-i440fx-2.2 Standard PC (i440FX + PIIX, 1996) (default)
> pc-1.2 Standard PC (i440FX + PIIX, 1996)
> pc-0.10 Standard PC (i440FX + PIIX, 1996)
> pc-0.11 Standard PC (i440FX + PIIX, 1996)
> pc-q35-2.1 Standard PC (Q35 + ICH9, 2009)
> q35 Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-2.2)
> pc-q35-2.2 Standard PC (Q35 + ICH9, 2009)
> pc-i440fx-1.6 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.7 Standard PC (i440FX + PIIX, 1996)
> none empty machine
> pc-q35-1.5 Standard PC (Q35 + ICH9, 2009)
> pc-q35-1.6 Standard PC (Q35 + ICH9, 2009)
> pc-0.12 Standard PC (i440FX + PIIX, 1996)
> pc-1.3 Standard PC (i440FX + PIIX, 1996)
After:
> Supported machines are:
> isapc ISA-only PC
> none empty machine
> pc-0.10 Standard PC (i440FX + PIIX, 1996)
> pc-0.11 Standard PC (i440FX + PIIX, 1996)
> pc-0.12 Standard PC (i440FX + PIIX, 1996)
> pc-0.13 Standard PC (i440FX + PIIX, 1996)
> pc-0.14 Standard PC (i440FX + PIIX, 1996)
> pc-0.15 Standard PC (i440FX + PIIX, 1996)
> pc-1.0 Standard PC (i440FX + PIIX, 1996)
> pc-1.1 Standard PC (i440FX + PIIX, 1996)
> pc-1.2 Standard PC (i440FX + PIIX, 1996)
> pc-1.3 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.4 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.5 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.6 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-1.7 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-2.0 Standard PC (i440FX + PIIX, 1996)
> pc-i440fx-2.1 Standard PC (i440FX + PIIX, 1996)
> pc Standard PC (i440FX + PIIX, 1996) (alias of pc-i440fx-2.2)
> pc-i440fx-2.2 Standard PC (i440FX + PIIX, 1996) (default)
> pc-q35-1.4 Standard PC (Q35 + ICH9, 2009)
> pc-q35-1.5 Standard PC (Q35 + ICH9, 2009)
> pc-q35-1.6 Standard PC (Q35 + ICH9, 2009)
> pc-q35-1.7 Standard PC (Q35 + ICH9, 2009)
> pc-q35-2.0 Standard PC (Q35 + ICH9, 2009)
> pc-q35-2.1 Standard PC (Q35 + ICH9, 2009)
> q35 Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-2.2)
> pc-q35-2.2 Standard PC (Q35 + ICH9, 2009)
Effects on the aarch64 output:
Before:
> Supported machines are:
> lm3s811evb Stellaris LM3S811EVB
> canon-a1100 Canon PowerShot A1100 IS
> vexpress-a15 ARM Versatile Express for Cortex-A15
> vexpress-a9 ARM Versatile Express for Cortex-A9
> xilinx-zynq-a9 Xilinx Zynq Platform Baseboard for Cortex-A9
> connex Gumstix Connex (PXA255)
> n800 Nokia N800 tablet aka. RX-34 (OMAP2420)
> lm3s6965evb Stellaris LM3S6965EVB
> versatileab ARM Versatile/AB (ARM926EJ-S)
> borzoi Borzoi PDA (PXA270)
> tosa Tosa PDA (PXA255)
> cheetah Palm Tungsten|E aka. Cheetah PDA (OMAP310)
> midway Calxeda Midway (ECX-2000)
> mainstone Mainstone II (PXA27x)
> n810 Nokia N810 tablet aka. RX-44 (OMAP2420)
> terrier Terrier PDA (PXA270)
> highbank Calxeda Highbank (ECX-1000)
> cubieboard cubietech cubieboard
> sx1-v1 Siemens SX1 (OMAP310) V1
> sx1 Siemens SX1 (OMAP310) V2
> realview-eb-mpcore ARM RealView Emulation Baseboard (ARM11MPCore)
> kzm ARM KZM Emulation Baseboard (ARM1136)
> akita Akita PDA (PXA270)
> z2 Zipit Z2 (PXA27x)
> musicpal Marvell 88w8618 / MusicPal (ARM926EJ-S)
> realview-pb-a8 ARM RealView Platform Baseboard for Cortex-A8
> versatilepb ARM Versatile/PB (ARM926EJ-S)
> realview-eb ARM RealView Emulation Baseboard (ARM926EJ-S)
> realview-pbx-a9 ARM RealView Platform Baseboard Explore for Cortex-A9
> spitz Spitz PDA (PXA270)
> none empty machine
> virt ARM Virtual Machine
> collie Collie PDA (SA-1110)
> smdkc210 Samsung SMDKC210 board (Exynos4210)
> verdex Gumstix Verdex (PXA270)
> nuri Samsung NURI board (Exynos4210)
> integratorcp ARM Integrator/CP (ARM926EJ-S)
After:
> Supported machines are:
> akita Akita PDA (PXA270)
> borzoi Borzoi PDA (PXA270)
> canon-a1100 Canon PowerShot A1100 IS
> cheetah Palm Tungsten|E aka. Cheetah PDA (OMAP310)
> collie Collie PDA (SA-1110)
> connex Gumstix Connex (PXA255)
> cubieboard cubietech cubieboard
> highbank Calxeda Highbank (ECX-1000)
> integratorcp ARM Integrator/CP (ARM926EJ-S)
> kzm ARM KZM Emulation Baseboard (ARM1136)
> lm3s6965evb Stellaris LM3S6965EVB
> lm3s811evb Stellaris LM3S811EVB
> mainstone Mainstone II (PXA27x)
> midway Calxeda Midway (ECX-2000)
> musicpal Marvell 88w8618 / MusicPal (ARM926EJ-S)
> n800 Nokia N800 tablet aka. RX-34 (OMAP2420)
> n810 Nokia N810 tablet aka. RX-44 (OMAP2420)
> none empty machine
> nuri Samsung NURI board (Exynos4210)
> realview-eb ARM RealView Emulation Baseboard (ARM926EJ-S)
> realview-eb-mpcore ARM RealView Emulation Baseboard (ARM11MPCore)
> realview-pb-a8 ARM RealView Platform Baseboard for Cortex-A8
> realview-pbx-a9 ARM RealView Platform Baseboard Explore for Cortex-A9
> smdkc210 Samsung SMDKC210 board (Exynos4210)
> spitz Spitz PDA (PXA270)
> sx1 Siemens SX1 (OMAP310) V2
> sx1-v1 Siemens SX1 (OMAP310) V1
> terrier Terrier PDA (PXA270)
> tosa Tosa PDA (PXA255)
> verdex Gumstix Verdex (PXA270)
> versatileab ARM Versatile/AB (ARM926EJ-S)
> versatilepb ARM Versatile/PB (ARM926EJ-S)
> vexpress-a15 ARM Versatile Express for Cortex-A15
> vexpress-a9 ARM Versatile Express for Cortex-A9
> virt ARM Virtual Machine
> xilinx-zynq-a9 Xilinx Zynq Platform Baseboard for Cortex-A9
> z2 Zipit Z2 (PXA27x)
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1145042
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel.a@redhat.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-22 22:38:35 +02:00
|
|
|
machines = g_slist_sort(machines, machine_class_cmp);
|
2014-03-14 13:06:54 +01:00
|
|
|
for (el = machines; el; el = el->next) {
|
|
|
|
MachineClass *mc = el->data;
|
2014-04-09 19:34:53 +02:00
|
|
|
if (mc->alias) {
|
|
|
|
printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
|
2014-03-14 13:06:54 +01:00
|
|
|
}
|
2014-04-09 19:34:53 +02:00
|
|
|
printf("%-20s %s%s\n", mc->name, mc->desc,
|
|
|
|
mc->is_default ? " (default)" : "");
|
2011-07-23 12:38:37 +02:00
|
|
|
}
|
|
|
|
}
|
2014-03-05 18:30:46 +01:00
|
|
|
|
|
|
|
g_slist_free(machines);
|
2012-08-02 14:45:54 +02:00
|
|
|
exit(!name || !is_help_option(name));
|
2011-07-23 12:38:37 +02:00
|
|
|
}
|
|
|
|
|
2010-06-04 14:08:07 +02:00
|
|
|
void qemu_add_exit_notifier(Notifier *notify)
|
|
|
|
{
|
|
|
|
notifier_list_add(&exit_notifiers, notify);
|
|
|
|
}
|
|
|
|
|
|
|
|
void qemu_remove_exit_notifier(Notifier *notify)
|
|
|
|
{
|
2012-01-13 17:34:01 +01:00
|
|
|
notifier_remove(notify);
|
2010-06-04 14:08:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void qemu_run_exit_notifiers(void)
|
|
|
|
{
|
2011-06-20 14:06:26 +02:00
|
|
|
notifier_list_notify(&exit_notifiers, NULL);
|
2010-06-04 14:08:07 +02:00
|
|
|
}
|
|
|
|
|
2015-03-31 14:01:06 +02:00
|
|
|
static bool machine_init_done;
|
|
|
|
|
2010-12-08 12:35:08 +01:00
|
|
|
void qemu_add_machine_init_done_notifier(Notifier *notify)
|
|
|
|
{
|
|
|
|
notifier_list_add(&machine_init_done_notifiers, notify);
|
2015-03-31 14:01:06 +02:00
|
|
|
if (machine_init_done) {
|
|
|
|
notify->notify(notify, NULL);
|
|
|
|
}
|
2010-12-08 12:35:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void qemu_run_machine_init_done_notifiers(void)
|
|
|
|
{
|
2011-06-20 14:06:26 +02:00
|
|
|
notifier_list_notify(&machine_init_done_notifiers, NULL);
|
2015-03-31 14:01:06 +02:00
|
|
|
machine_init_done = true;
|
2010-12-08 12:35:08 +01:00
|
|
|
}
|
|
|
|
|
2010-01-22 16:18:06 +01: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 20:13:51 +01:00
|
|
|
loc_set_cmdline(argv, optind, 1);
|
2010-01-22 16:18:06 +01:00
|
|
|
optind++;
|
|
|
|
/* Treat --foo the same as -foo. */
|
|
|
|
if (r[1] == '-')
|
|
|
|
r++;
|
|
|
|
popt = qemu_options;
|
|
|
|
for(;;) {
|
|
|
|
if (!popt->name) {
|
2010-02-18 20:13:51 +01:00
|
|
|
error_report("invalid option");
|
2010-01-22 16:18:06 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (!strcmp(popt->name, r + 1))
|
|
|
|
break;
|
|
|
|
popt++;
|
|
|
|
}
|
|
|
|
if (popt->flags & HAS_ARG) {
|
|
|
|
if (optind >= argc) {
|
2010-02-18 20:13:51 +01:00
|
|
|
error_report("requires an argument");
|
2010-01-22 16:18:06 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
optarg = argv[optind++];
|
2010-02-18 20:13:51 +01:00
|
|
|
loc_set_cmdline(argv, optind - 2, 2);
|
2010-01-22 16:18:06 +01:00
|
|
|
} else {
|
|
|
|
optarg = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*poptarg = optarg;
|
|
|
|
*poptind = optind;
|
|
|
|
|
|
|
|
return popt;
|
|
|
|
}
|
|
|
|
|
2011-08-21 05:38:31 +02:00
|
|
|
static gpointer malloc_and_trace(gsize n_bytes)
|
|
|
|
{
|
|
|
|
void *ptr = malloc(n_bytes);
|
2011-08-31 09:25:35 +02:00
|
|
|
trace_g_malloc(n_bytes, ptr);
|
2011-08-21 05:38:31 +02:00
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gpointer realloc_and_trace(gpointer mem, gsize n_bytes)
|
|
|
|
{
|
|
|
|
void *ptr = realloc(mem, n_bytes);
|
2011-08-31 09:25:35 +02:00
|
|
|
trace_g_realloc(mem, n_bytes, ptr);
|
2011-08-21 05:38:31 +02:00
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_and_trace(gpointer mem)
|
|
|
|
{
|
2011-08-31 09:25:35 +02:00
|
|
|
trace_g_free(mem);
|
2011-08-21 05:38:31 +02:00
|
|
|
free(mem);
|
|
|
|
}
|
|
|
|
|
2015-03-12 08:40:25 +01:00
|
|
|
static int machine_set_property(void *opaque,
|
|
|
|
const char *name, const char *value,
|
|
|
|
Error **errp)
|
2012-06-25 21:36:33 +02:00
|
|
|
{
|
|
|
|
Object *obj = OBJECT(opaque);
|
|
|
|
Error *local_err = NULL;
|
2014-07-18 18:32:37 +02:00
|
|
|
char *c, *qom_name;
|
2012-06-25 21:36:33 +02:00
|
|
|
|
2014-07-23 16:16:26 +02:00
|
|
|
if (strcmp(name, "type") == 0) {
|
2012-06-25 21:36:33 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-18 18:32:37 +02:00
|
|
|
qom_name = g_strdup(name);
|
|
|
|
c = qom_name;
|
|
|
|
while (*c++) {
|
|
|
|
if (*c == '_') {
|
|
|
|
*c = '-';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-16 17:58:05 +01:00
|
|
|
object_property_parse(obj, value, qom_name, &local_err);
|
2014-07-18 18:32:37 +02:00
|
|
|
g_free(qom_name);
|
2012-06-25 21:36:33 +02:00
|
|
|
|
|
|
|
if (local_err) {
|
2015-02-10 15:12:59 +01:00
|
|
|
error_report_err(local_err);
|
2012-06-25 21:36:33 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
static int object_create(void *opaque, QemuOpts *opts, Error **errp)
|
2012-06-25 21:36:33 +02:00
|
|
|
{
|
2014-06-10 13:15:15 +02:00
|
|
|
Error *err = NULL;
|
|
|
|
char *type = NULL;
|
|
|
|
char *id = NULL;
|
|
|
|
void *dummy = NULL;
|
|
|
|
OptsVisitor *ov;
|
|
|
|
QDict *pdict;
|
2012-06-25 21:36:33 +02:00
|
|
|
|
2014-06-10 13:15:15 +02:00
|
|
|
ov = opts_visitor_new(opts);
|
|
|
|
pdict = qemu_opts_to_qdict(opts, NULL);
|
2012-06-25 21:36:33 +02:00
|
|
|
|
2014-06-10 13:15:15 +02:00
|
|
|
visit_start_struct(opts_get_visitor(ov), &dummy, NULL, NULL, 0, &err);
|
|
|
|
if (err) {
|
|
|
|
goto out;
|
2012-06-25 21:36:33 +02:00
|
|
|
}
|
|
|
|
|
2014-06-10 13:15:15 +02:00
|
|
|
qdict_del(pdict, "qom-type");
|
|
|
|
visit_type_str(opts_get_visitor(ov), &type, "qom-type", &err);
|
|
|
|
if (err) {
|
|
|
|
goto out;
|
2012-06-25 21:36:33 +02:00
|
|
|
}
|
|
|
|
|
2014-06-10 13:15:15 +02:00
|
|
|
qdict_del(pdict, "id");
|
|
|
|
visit_type_str(opts_get_visitor(ov), &id, "id", &err);
|
|
|
|
if (err) {
|
2014-01-16 17:34:38 +01:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2014-06-10 13:15:15 +02:00
|
|
|
object_add(type, id, pdict, opts_get_visitor(ov), &err);
|
|
|
|
if (err) {
|
2014-01-16 17:34:38 +01:00
|
|
|
goto out;
|
|
|
|
}
|
2014-06-10 13:15:15 +02:00
|
|
|
visit_end_struct(opts_get_visitor(ov), &err);
|
|
|
|
if (err) {
|
|
|
|
qmp_object_del(id, NULL);
|
|
|
|
}
|
|
|
|
|
2014-01-16 17:34:38 +01:00
|
|
|
out:
|
2014-06-10 13:15:15 +02:00
|
|
|
opts_visitor_cleanup(ov);
|
|
|
|
|
|
|
|
QDECREF(pdict);
|
|
|
|
g_free(id);
|
|
|
|
g_free(type);
|
|
|
|
g_free(dummy);
|
|
|
|
if (err) {
|
2015-02-10 15:12:59 +01:00
|
|
|
error_report_err(err);
|
2014-01-16 17:34:37 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2012-06-25 21:36:33 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-05-07 07:33:57 +02:00
|
|
|
static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size,
|
|
|
|
MachineClass *mc)
|
2015-01-11 11:38:43 +01:00
|
|
|
{
|
|
|
|
uint64_t sz;
|
|
|
|
const char *mem_str;
|
|
|
|
const char *maxmem_str, *slots_str;
|
2015-05-07 07:33:57 +02:00
|
|
|
const ram_addr_t default_ram_size = mc->default_ram_size;
|
2015-01-11 11:38:43 +01:00
|
|
|
QemuOpts *opts = qemu_find_opts_singleton("memory");
|
|
|
|
|
|
|
|
sz = 0;
|
|
|
|
mem_str = qemu_opt_get(opts, "size");
|
|
|
|
if (mem_str) {
|
|
|
|
if (!*mem_str) {
|
|
|
|
error_report("missing 'size' option value");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
sz = qemu_opt_get_size(opts, "size", ram_size);
|
|
|
|
|
|
|
|
/* Fix up legacy suffix-less format */
|
|
|
|
if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
|
|
|
|
uint64_t overflow_check = sz;
|
|
|
|
|
|
|
|
sz <<= 20;
|
|
|
|
if ((sz >> 20) != overflow_check) {
|
|
|
|
error_report("too large 'size' option value");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* backward compatibility behaviour for case "-m 0" */
|
|
|
|
if (sz == 0) {
|
|
|
|
sz = default_ram_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
sz = QEMU_ALIGN_UP(sz, 8192);
|
|
|
|
ram_size = sz;
|
|
|
|
if (ram_size != sz) {
|
|
|
|
error_report("ram size too large");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* store value for the future use */
|
2015-02-12 16:46:36 +01:00
|
|
|
qemu_opt_set_number(opts, "size", ram_size, &error_abort);
|
2015-01-11 11:38:43 +01:00
|
|
|
*maxram_size = ram_size;
|
|
|
|
|
|
|
|
maxmem_str = qemu_opt_get(opts, "maxmem");
|
|
|
|
slots_str = qemu_opt_get(opts, "slots");
|
|
|
|
if (maxmem_str && slots_str) {
|
|
|
|
uint64_t slots;
|
|
|
|
|
|
|
|
sz = qemu_opt_get_size(opts, "maxmem", 0);
|
2015-01-29 14:48:40 +01:00
|
|
|
slots = qemu_opt_get_number(opts, "slots", 0);
|
2015-01-11 11:38:43 +01:00
|
|
|
if (sz < ram_size) {
|
2015-01-29 14:48:40 +01:00
|
|
|
error_report("invalid value of -m option maxmem: "
|
|
|
|
"maximum memory size (0x%" PRIx64 ") must be at least "
|
|
|
|
"the initial memory size (0x" RAM_ADDR_FMT ")",
|
|
|
|
sz, ram_size);
|
2015-01-11 11:38:43 +01:00
|
|
|
exit(EXIT_FAILURE);
|
2015-01-29 14:48:40 +01:00
|
|
|
} else if (sz > ram_size) {
|
|
|
|
if (!slots) {
|
|
|
|
error_report("invalid value of -m option: maxmem was "
|
|
|
|
"specified, but no hotplug slots were specified");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
} else if (slots) {
|
|
|
|
error_report("invalid value of -m option maxmem: "
|
|
|
|
"memory slots were specified but maximum memory size "
|
|
|
|
"(0x%" PRIx64 ") is equal to the initial memory size "
|
|
|
|
"(0x" RAM_ADDR_FMT ")", sz, ram_size);
|
2015-01-11 11:38:43 +01:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
*maxram_size = sz;
|
|
|
|
*ram_slots = slots;
|
|
|
|
} else if ((!maxmem_str && slots_str) ||
|
|
|
|
(maxmem_str && !slots_str)) {
|
|
|
|
error_report("invalid -m option value: missing "
|
|
|
|
"'%s' option", slots_str ? "maxmem" : "slots");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-10 20:18:40 +01:00
|
|
|
int main(int argc, char **argv, char **envp)
|
2003-06-24 15:42:40 +02:00
|
|
|
{
|
2007-12-02 05:51:10 +01:00
|
|
|
int i;
|
net: remove broken net_set_boot_mask() boot device validation
There are many problems with net_set_boot_mask():
1) It is broken when using the device model instead of "-net nic". Example:
$ qemu-system-x86_64 -device rtl8139,vlan=0,id=net0,mac=52:54:00:82:41:fd,bus=pci.0,addr=0x4 -net user,vlan=0,name=hostnet0 -vnc 0.0.0.0:0 -boot n
Cannot boot from non-existent NIC
$
2) The mask was previously used to set which boot ROMs were supposed to be
loaded, but this was changed long time ago. Now all ROM images are loaded,
and SeaBIOS takes care of jumping to the right boot entry point depending on
the boot settings.
3) Interpretation and validation of the boot parameter letters is done on
the machine type code. Examples: PC accepts only a,b,c,d,n as valid boot
device letters. mac99 accepts only a,b,c,d,e,f.
As a side-effect of this change, qemu-kvm won't abort anymore if using "-boot n"
on a machine with no network devices. Checking if the requested boot device is
valid is now a task for the BIOS or the machine-type code.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Acked-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2010-04-07 00:22:07 +02:00
|
|
|
int snapshot, linux_boot;
|
2003-10-30 02:11:23 +01:00
|
|
|
const char *initrd_filename;
|
2003-09-30 23:07:02 +02:00
|
|
|
const char *kernel_filename, *kernel_cmdline;
|
2015-02-03 12:31:09 +01:00
|
|
|
const char *boot_order = NULL;
|
|
|
|
const char *boot_once = NULL;
|
2009-01-16 20:04:14 +01:00
|
|
|
DisplayState *ds;
|
2012-08-27 16:33:22 +02:00
|
|
|
int cyls, heads, secs, translation;
|
2014-07-25 11:56:28 +02:00
|
|
|
QemuOpts *hda_opts = NULL, *opts, *machine_opts, *icount_opts = NULL;
|
2010-08-20 13:52:02 +02:00
|
|
|
QemuOptsList *olist;
|
2004-05-14 00:02:20 +02:00
|
|
|
int optind;
|
2010-01-22 16:18:06 +01:00
|
|
|
const char *optarg;
|
2004-10-03 15:29:03 +02:00
|
|
|
const char *loadvm = NULL;
|
2014-03-05 18:30:47 +01:00
|
|
|
MachineClass *machine_class;
|
2007-03-05 20:44:02 +01:00
|
|
|
const char *cpu_model;
|
2014-03-10 15:37:40 +01:00
|
|
|
const char *vga_model = NULL;
|
2013-10-18 13:51:11 +02:00
|
|
|
const char *qtest_chrdev = NULL;
|
|
|
|
const char *qtest_log = NULL;
|
2007-03-19 16:58:31 +01:00
|
|
|
const char *pid_file = NULL;
|
2008-10-13 05:12:02 +02:00
|
|
|
const char *incoming = NULL;
|
2011-03-16 13:33:36 +01:00
|
|
|
#ifdef CONFIG_VNC
|
2009-05-21 23:54:00 +02:00
|
|
|
int show_vnc_port = 0;
|
2011-03-16 13:33:36 +01:00
|
|
|
#endif
|
2012-05-02 18:07:28 +02:00
|
|
|
bool defconfig = true;
|
2012-05-02 18:07:29 +02:00
|
|
|
bool userconfig = true;
|
2011-06-07 18:32:40 +02:00
|
|
|
const char *log_mask = NULL;
|
|
|
|
const char *log_file = NULL;
|
2011-08-21 05:38:31 +02:00
|
|
|
GMemVTable mem_trace = {
|
|
|
|
.malloc = malloc_and_trace,
|
|
|
|
.realloc = realloc_and_trace,
|
|
|
|
.free = free_and_trace,
|
|
|
|
};
|
2011-08-31 20:31:31 +02:00
|
|
|
const char *trace_events = NULL;
|
2011-08-31 20:31:03 +02:00
|
|
|
const char *trace_file = NULL;
|
2015-01-11 11:38:43 +01:00
|
|
|
ram_addr_t maxram_size;
|
2014-06-02 15:25:02 +02:00
|
|
|
uint64_t ram_slots = 0;
|
2014-06-20 15:26:08 +02:00
|
|
|
FILE *vmstate_dump_file = NULL;
|
2014-09-18 13:30:49 +02:00
|
|
|
Error *main_loop_err = NULL;
|
2011-02-26 19:38:39 +01:00
|
|
|
|
2015-03-03 11:36:09 +01:00
|
|
|
qemu_init_cpu_loop();
|
|
|
|
qemu_mutex_lock_iothread();
|
|
|
|
|
2010-06-04 14:08:07 +02:00
|
|
|
atexit(qemu_run_exit_notifiers);
|
2010-02-24 14:37:14 +01:00
|
|
|
error_set_progname(argv[0]);
|
2014-02-10 07:48:51 +01:00
|
|
|
qemu_init_exec_dir(argv[0]);
|
2010-02-24 14:37:14 +01:00
|
|
|
|
2011-08-21 05:38:31 +02:00
|
|
|
g_mem_set_vtable(&mem_trace);
|
|
|
|
|
2012-03-04 21:32:35 +01:00
|
|
|
module_call_init(MODULE_INIT_QOM);
|
|
|
|
|
2012-11-26 16:03:42 +01:00
|
|
|
qemu_add_opts(&qemu_drive_opts);
|
2013-11-09 05:15:47 +01:00
|
|
|
qemu_add_drive_opts(&qemu_legacy_drive_opts);
|
|
|
|
qemu_add_drive_opts(&qemu_common_drive_opts);
|
|
|
|
qemu_add_drive_opts(&qemu_drive_opts);
|
2012-11-26 16:03:42 +01:00
|
|
|
qemu_add_opts(&qemu_chardev_opts);
|
|
|
|
qemu_add_opts(&qemu_device_opts);
|
|
|
|
qemu_add_opts(&qemu_netdev_opts);
|
|
|
|
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);
|
|
|
|
qemu_add_opts(&qemu_option_rom_opts);
|
|
|
|
qemu_add_opts(&qemu_machine_opts);
|
2013-11-27 01:27:35 +01: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 13:06:52 +02:00
|
|
|
qemu_add_opts(&qemu_smp_opts);
|
2012-11-26 16:03:42 +01:00
|
|
|
qemu_add_opts(&qemu_boot_opts);
|
|
|
|
qemu_add_opts(&qemu_sandbox_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 18:47:49 +01:00
|
|
|
qemu_add_opts(&qemu_tpmdev_opts);
|
2013-04-19 16:42:06 +02:00
|
|
|
qemu_add_opts(&qemu_realtime_opts);
|
2013-07-04 05:02:46 +02:00
|
|
|
qemu_add_opts(&qemu_msg_opts);
|
2014-01-30 11:20:30 +01:00
|
|
|
qemu_add_opts(&qemu_name_opts);
|
2014-05-14 11:43:08 +02:00
|
|
|
qemu_add_opts(&qemu_numa_opts);
|
2014-07-25 11:56:28 +02:00
|
|
|
qemu_add_opts(&qemu_icount_opts);
|
2014-12-11 13:07:48 +01:00
|
|
|
qemu_add_opts(&qemu_semihosting_config_opts);
|
2015-04-29 17:21:53 +02:00
|
|
|
qemu_add_opts(&qemu_fw_cfg_opts);
|
2012-11-26 16:03:42 +01:00
|
|
|
|
2011-09-05 21:36:31 +02:00
|
|
|
runstate_init();
|
|
|
|
|
2013-08-21 17:03:04 +02:00
|
|
|
rtc_clock = QEMU_CLOCK_HOST;
|
2009-09-15 13:36:04 +02:00
|
|
|
|
2009-09-12 09:36:22 +02:00
|
|
|
QLIST_INIT (&vm_change_state_head);
|
2010-06-10 11:42:21 +02:00
|
|
|
os_setup_early_signal_handling();
|
2006-06-25 18:25:21 +02:00
|
|
|
|
2009-05-21 01:38:09 +02:00
|
|
|
module_call_init(MODULE_INIT_MACHINE);
|
2014-03-05 18:30:47 +01:00
|
|
|
machine_class = find_default_machine();
|
2007-03-05 20:44:02 +01:00
|
|
|
cpu_model = NULL;
|
2003-07-06 19:15:21 +02:00
|
|
|
snapshot = 0;
|
2012-08-27 16:33:22 +02:00
|
|
|
cyls = heads = secs = 0;
|
|
|
|
translation = BIOS_ATA_TRANSLATION_AUTO;
|
2004-03-14 22:44:30 +01:00
|
|
|
|
2005-11-15 23:16:05 +01:00
|
|
|
nb_nics = 0;
|
2007-09-17 10:09:54 +02:00
|
|
|
|
2013-03-21 13:07:10 +01:00
|
|
|
bdrv_init_with_whitelist();
|
|
|
|
|
2013-12-31 11:36:08 +01:00
|
|
|
autostart = 1;
|
2008-10-05 11:56:21 +02:00
|
|
|
|
2010-01-21 17:57:58 +01:00
|
|
|
/* first pass of option parsing */
|
|
|
|
optind = 1;
|
|
|
|
while (optind < argc) {
|
|
|
|
if (argv[optind][0] != '-') {
|
|
|
|
/* disk image */
|
2010-01-27 17:46:00 +01:00
|
|
|
optind++;
|
2010-01-21 17:57:58 +01:00
|
|
|
} else {
|
|
|
|
const QEMUOption *popt;
|
|
|
|
|
|
|
|
popt = lookup_opt(argc, argv, &optarg, &optind);
|
|
|
|
switch (popt->index) {
|
|
|
|
case QEMU_OPTION_nodefconfig:
|
2012-05-02 18:07:28 +02:00
|
|
|
defconfig = false;
|
2010-01-21 17:57:58 +01:00
|
|
|
break;
|
2012-05-02 18:07:29 +02:00
|
|
|
case QEMU_OPTION_nouserconfig:
|
|
|
|
userconfig = false;
|
|
|
|
break;
|
2010-01-21 17:57:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defconfig) {
|
2010-03-05 17:25:55 +01:00
|
|
|
int ret;
|
2012-05-02 18:07:29 +02:00
|
|
|
ret = qemu_read_default_config_files(userconfig);
|
2012-05-02 18:07:25 +02:00
|
|
|
if (ret < 0) {
|
2010-03-05 17:25:55 +01:00
|
|
|
exit(1);
|
2010-01-21 17:57:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* second pass of option parsing */
|
2004-05-14 00:02:20 +02:00
|
|
|
optind = 1;
|
2003-06-24 15:42:40 +02:00
|
|
|
for(;;) {
|
2004-05-14 00:02:20 +02:00
|
|
|
if (optind >= argc)
|
2003-06-24 15:42:40 +02:00
|
|
|
break;
|
2010-01-22 16:18:06 +01:00
|
|
|
if (argv[optind][0] != '-') {
|
2015-01-11 11:56:51 +01:00
|
|
|
hda_opts = drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS);
|
2004-05-14 00:02:20 +02:00
|
|
|
} else {
|
|
|
|
const QEMUOption *popt;
|
|
|
|
|
2010-01-22 16:18:06 +01:00
|
|
|
popt = lookup_opt(argc, argv, &optarg, &optind);
|
2010-03-29 21:23:52 +02:00
|
|
|
if (!(popt->arch_mask & arch_type)) {
|
|
|
|
printf("Option %s not supported for this target\n", popt->name);
|
|
|
|
exit(1);
|
|
|
|
}
|
2004-05-14 00:02:20 +02:00
|
|
|
switch(popt->index) {
|
2012-10-05 19:51:40 +02:00
|
|
|
case QEMU_OPTION_no_kvm_irqchip: {
|
|
|
|
olist = qemu_find_opts("machine");
|
|
|
|
qemu_opts_parse(olist, "kernel_irqchip=off", 0);
|
|
|
|
break;
|
|
|
|
}
|
2007-03-05 20:44:02 +01:00
|
|
|
case QEMU_OPTION_cpu:
|
|
|
|
/* hw initialization will check this */
|
2012-03-09 20:19:07 +01:00
|
|
|
cpu_model = optarg;
|
2007-03-05 20:44:02 +01:00
|
|
|
break;
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_hda:
|
2012-08-27 16:33:22 +02:00
|
|
|
{
|
|
|
|
char buf[256];
|
|
|
|
if (cyls == 0)
|
|
|
|
snprintf(buf, sizeof(buf), "%s", HD_OPTS);
|
|
|
|
else
|
|
|
|
snprintf(buf, sizeof(buf),
|
|
|
|
"%s,cyls=%d,heads=%d,secs=%d%s",
|
|
|
|
HD_OPTS , cyls, heads, secs,
|
|
|
|
translation == BIOS_ATA_TRANSLATION_LBA ?
|
|
|
|
",trans=lba" :
|
|
|
|
translation == BIOS_ATA_TRANSLATION_NONE ?
|
|
|
|
",trans=none" : "");
|
|
|
|
drive_add(IF_DEFAULT, 0, optarg, buf);
|
|
|
|
break;
|
|
|
|
}
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_hdb:
|
2005-06-05 16:49:17 +02:00
|
|
|
case QEMU_OPTION_hdc:
|
|
|
|
case QEMU_OPTION_hdd:
|
2011-01-28 11:21:41 +01:00
|
|
|
drive_add(IF_DEFAULT, popt->index - QEMU_OPTION_hda, optarg,
|
|
|
|
HD_OPTS);
|
2003-06-30 12:03:06 +02:00
|
|
|
break;
|
2007-12-02 05:51:10 +01:00
|
|
|
case QEMU_OPTION_drive:
|
exit if -drive specified is invalid instead of ignoring the "wrong" -drive
This fixes the problem when qemu continues even if -drive specification
is somehow invalid, resulting in a mess. Applicable for both current
master and for stable-0.14 (and the same issue exist 0.13 and 0.12 too).
The prob can actually be seriuos: when you start guest with two drives
and make an error in the specification of one of them, and the guest
has something like a raid array on the two drives, guest may start failing
that array or kick "missing" drives which may result in a mess - this is
what actually happened to me, I did't want a resync at all, and a resync
resulted in re-writing (and allocating) a 4TB virtual drive I used for
testing, which in turn resulted in my filesystem filling up and whole
thing failing badly. Yes it was just testing VM, I experimented with
larger raid arrays, but the end result was quite, well, unexpected.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-03-30 14:31:05 +02:00
|
|
|
if (drive_def(optarg) == NULL) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2015-01-11 11:56:51 +01:00
|
|
|
break;
|
2009-07-31 12:25:36 +02:00
|
|
|
case QEMU_OPTION_set:
|
|
|
|
if (qemu_set_option(optarg) != 0)
|
|
|
|
exit(1);
|
2015-01-11 11:56:51 +01:00
|
|
|
break;
|
2009-12-08 13:11:34 +01:00
|
|
|
case QEMU_OPTION_global:
|
|
|
|
if (qemu_global_option(optarg) != 0)
|
|
|
|
exit(1);
|
2015-01-11 11:56:51 +01:00
|
|
|
break;
|
2007-04-30 04:09:25 +02:00
|
|
|
case QEMU_OPTION_mtdblock:
|
2011-01-28 11:21:41 +01:00
|
|
|
drive_add(IF_MTD, -1, optarg, MTD_OPTS);
|
2007-04-30 04:09:25 +02:00
|
|
|
break;
|
2007-04-06 18:49:48 +02:00
|
|
|
case QEMU_OPTION_sd:
|
2013-02-28 19:23:14 +01:00
|
|
|
drive_add(IF_SD, -1, optarg, SD_OPTS);
|
2007-04-06 18:49:48 +02:00
|
|
|
break;
|
2007-04-24 08:52:59 +02:00
|
|
|
case QEMU_OPTION_pflash:
|
2011-01-28 11:21:41 +01:00
|
|
|
drive_add(IF_PFLASH, -1, optarg, PFLASH_OPTS);
|
2007-04-24 08:52:59 +02:00
|
|
|
break;
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_snapshot:
|
2003-07-06 19:15:21 +02:00
|
|
|
snapshot = 1;
|
|
|
|
break;
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_hdachs:
|
2003-07-26 20:11:40 +02:00
|
|
|
{
|
|
|
|
const char *p;
|
|
|
|
p = optarg;
|
|
|
|
cyls = strtol(p, (char **)&p, 0);
|
2004-11-16 02:45:27 +01:00
|
|
|
if (cyls < 1 || cyls > 16383)
|
|
|
|
goto chs_fail;
|
2003-07-26 20:11:40 +02:00
|
|
|
if (*p != ',')
|
|
|
|
goto chs_fail;
|
|
|
|
p++;
|
|
|
|
heads = strtol(p, (char **)&p, 0);
|
2004-11-16 02:45:27 +01:00
|
|
|
if (heads < 1 || heads > 16)
|
|
|
|
goto chs_fail;
|
2003-07-26 20:11:40 +02:00
|
|
|
if (*p != ',')
|
|
|
|
goto chs_fail;
|
|
|
|
p++;
|
|
|
|
secs = strtol(p, (char **)&p, 0);
|
2004-11-16 02:45:27 +01:00
|
|
|
if (secs < 1 || secs > 63)
|
|
|
|
goto chs_fail;
|
|
|
|
if (*p == ',') {
|
|
|
|
p++;
|
2014-02-08 11:01:54 +01:00
|
|
|
if (!strcmp(p, "large")) {
|
|
|
|
translation = BIOS_ATA_TRANSLATION_LARGE;
|
|
|
|
} else if (!strcmp(p, "rechs")) {
|
|
|
|
translation = BIOS_ATA_TRANSLATION_RECHS;
|
|
|
|
} else if (!strcmp(p, "none")) {
|
2004-11-16 02:45:27 +01:00
|
|
|
translation = BIOS_ATA_TRANSLATION_NONE;
|
2014-02-08 11:01:54 +01:00
|
|
|
} else if (!strcmp(p, "lba")) {
|
2004-11-16 02:45:27 +01:00
|
|
|
translation = BIOS_ATA_TRANSLATION_LBA;
|
2014-02-08 11:01:54 +01:00
|
|
|
} else if (!strcmp(p, "auto")) {
|
2004-11-16 02:45:27 +01:00
|
|
|
translation = BIOS_ATA_TRANSLATION_AUTO;
|
2014-02-08 11:01:54 +01:00
|
|
|
} else {
|
2004-11-16 02:45:27 +01:00
|
|
|
goto chs_fail;
|
2014-02-08 11:01:54 +01:00
|
|
|
}
|
2004-11-16 02:45:27 +01:00
|
|
|
} else if (*p != '\0') {
|
2004-03-14 22:44:30 +01:00
|
|
|
chs_fail:
|
2004-11-16 02:45:27 +01:00
|
|
|
fprintf(stderr, "qemu: invalid physical CHS format\n");
|
|
|
|
exit(1);
|
2004-03-14 22:44:30 +01:00
|
|
|
}
|
2015-01-11 11:56:51 +01:00
|
|
|
if (hda_opts != NULL) {
|
2015-02-13 15:50:43 +01:00
|
|
|
qemu_opt_set_number(hda_opts, "cyls", cyls,
|
|
|
|
&error_abort);
|
|
|
|
qemu_opt_set_number(hda_opts, "heads", heads,
|
|
|
|
&error_abort);
|
|
|
|
qemu_opt_set_number(hda_opts, "secs", secs,
|
|
|
|
&error_abort);
|
2014-02-08 11:01:54 +01:00
|
|
|
if (translation == BIOS_ATA_TRANSLATION_LARGE) {
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(hda_opts, "trans", "large",
|
|
|
|
&error_abort);
|
2014-02-08 11:01:54 +01:00
|
|
|
} else if (translation == BIOS_ATA_TRANSLATION_RECHS) {
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(hda_opts, "trans", "rechs",
|
|
|
|
&error_abort);
|
2014-02-08 11:01:54 +01:00
|
|
|
} else if (translation == BIOS_ATA_TRANSLATION_LBA) {
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(hda_opts, "trans", "lba",
|
|
|
|
&error_abort);
|
2014-02-08 11:01:54 +01:00
|
|
|
} else if (translation == BIOS_ATA_TRANSLATION_NONE) {
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(hda_opts, "trans", "none",
|
|
|
|
&error_abort);
|
2014-02-08 11:01:54 +01:00
|
|
|
}
|
2009-07-22 16:43:04 +02:00
|
|
|
}
|
2003-07-26 20:11:40 +02:00
|
|
|
}
|
|
|
|
break;
|
2009-04-22 00:30:27 +02:00
|
|
|
case QEMU_OPTION_numa:
|
2014-05-14 11:43:08 +02:00
|
|
|
opts = qemu_opts_parse(qemu_find_opts("numa"), optarg, 1);
|
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2009-04-22 00:30:27 +02:00
|
|
|
break;
|
2011-03-16 13:33:31 +01:00
|
|
|
case QEMU_OPTION_display:
|
|
|
|
display_type = select_display(optarg);
|
|
|
|
break;
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_nographic:
|
2009-05-21 23:54:00 +02:00
|
|
|
display_type = DT_NOGRAPHIC;
|
2003-09-30 23:07:02 +02:00
|
|
|
break;
|
2008-02-10 17:33:14 +01:00
|
|
|
case QEMU_OPTION_curses:
|
2011-03-16 13:33:35 +01:00
|
|
|
#ifdef CONFIG_CURSES
|
2009-05-21 23:54:00 +02:00
|
|
|
display_type = DT_CURSES;
|
2011-03-16 13:33:35 +01:00
|
|
|
#else
|
|
|
|
fprintf(stderr, "Curses support is disabled\n");
|
|
|
|
exit(1);
|
2008-02-10 17:33:14 +01:00
|
|
|
#endif
|
2011-03-16 13:33:35 +01:00
|
|
|
break;
|
2007-04-30 03:48:07 +02:00
|
|
|
case QEMU_OPTION_portrait:
|
2011-06-17 12:04:36 +02: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) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"qemu: only 90, 180, 270 deg rotation is available\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2007-04-30 03:48:07 +02:00
|
|
|
break;
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_kernel:
|
2015-02-12 17:07:34 +01:00
|
|
|
qemu_opts_set(qemu_find_opts("machine"), 0, "kernel", optarg,
|
|
|
|
&error_abort);
|
2012-02-08 06:41:39 +01:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_initrd:
|
2015-02-12 17:07:34 +01:00
|
|
|
qemu_opts_set(qemu_find_opts("machine"), 0, "initrd", optarg,
|
|
|
|
&error_abort);
|
2003-09-30 23:07:02 +02:00
|
|
|
break;
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_append:
|
2015-02-12 17:07:34 +01:00
|
|
|
qemu_opts_set(qemu_find_opts("machine"), 0, "append", optarg,
|
|
|
|
&error_abort);
|
2003-08-10 23:52:11 +02:00
|
|
|
break;
|
2012-03-02 12:56:38 +01:00
|
|
|
case QEMU_OPTION_dtb:
|
2015-02-12 17:07:34 +01:00
|
|
|
qemu_opts_set(qemu_find_opts("machine"), 0, "dtb", optarg,
|
|
|
|
&error_abort);
|
2012-03-02 12:56:38 +01:00
|
|
|
break;
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_cdrom:
|
2011-01-28 11:21:41 +01:00
|
|
|
drive_add(IF_DEFAULT, 2, optarg, CDROM_OPTS);
|
2003-11-11 14:36:08 +01:00
|
|
|
break;
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_boot:
|
vl: Fix -boot order and once regressions, and related bugs
Option "once" sets up a different boot order just for the initial
boot. Boot order reverts back to normal on reset. Option "order"
changes the normal boot order.
The reversal is implemented by reset handler restore_boot_devices(),
which takes the boot order to revert to as argument.
restore_boot_devices() does nothing on its first call, because that
must be the initial machine reset. On its second call, it changes the
boot order back, and unregisters itself.
Because we register the handler right when -boot gets parsed, we can
revert to an incorrect normal boot order, and multiple -boot can
interact in funny ways.
Here's how things work without -boot once or order:
* boot_devices is "".
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "". machine->init() configures firmware
accordingly. For PC machines, machine->boot_order is "cad", and
pc_cmos_init() writes it to RTC CMOS, where SeaBIOS picks it up.
Now consider -boot order=:
* boot_devices is "".
* -boot order= sets boot_devices to "" (no change).
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "", as above.
Bug: -boot order= has no effect. Broken in commit e4ada29e.
Next, consider -boot once=a:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* main() passes boot_devices "a" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "a".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of machine->boot_order. The
actual boot order depends on how firmware interprets "". Broken
in commit e4ada29e.
Next, consider -boot once=a -boot order=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot order=c sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "c".
Bug: it should be "a". I figure this has always been broken.
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of "c". I figure this has
always been broken, just differently broken before commit
e4ada29e.
Next, consider -boot once=a -boot once=b -boot once=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot once=b registers restore_boot_devices() with argument "a", and
sets boot_devices to "b".
* -boot once=c registers restore_boot_devices() with argument "b", and
sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
- restore_boot_devices() gets called with argument "a". Calls
qemu_boot_set("a") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
- restore_boot_devices() gets called with argument "b". Calls
qemu_boot_set("b") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
* Machine boots, boot order is "b".
Bug: should really be "c", because that came last, and for all other
-boot options, the last one wins. I figure this was broken some
time before commit 37905d6a, and fixed there only for a single
occurence of "once".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Same bug as above: boot order reverts to "" instead of
machine->boot_order.
Fix by acting upon -boot options order, once and menu only after
option parsing is complete, and the machine is known. This is how the
other -boot options work already.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1371208516-7857-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-14 13:15:03 +02:00
|
|
|
opts = qemu_opts_parse(qemu_find_opts("boot-opts"), optarg, 1);
|
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
2003-11-11 14:36:08 +01:00
|
|
|
}
|
|
|
|
break;
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_fda:
|
|
|
|
case QEMU_OPTION_fdb:
|
2011-01-28 11:21:41 +01:00
|
|
|
drive_add(IF_FLOPPY, popt->index - QEMU_OPTION_fda,
|
|
|
|
optarg, FD_OPTS);
|
2004-01-05 01:02:06 +01:00
|
|
|
break;
|
2006-06-14 18:03:05 +02:00
|
|
|
case QEMU_OPTION_no_fd_bootchk:
|
|
|
|
fd_bootchk = 0;
|
|
|
|
break;
|
2009-10-08 20:58:26 +02:00
|
|
|
case QEMU_OPTION_netdev:
|
2010-08-20 13:52:01 +02:00
|
|
|
if (net_client_parse(qemu_find_opts("netdev"), optarg) == -1) {
|
2009-10-08 20:58:26 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2005-11-15 23:16:05 +01:00
|
|
|
case QEMU_OPTION_net:
|
2010-08-20 13:52:01 +02:00
|
|
|
if (net_client_parse(qemu_find_opts("net"), optarg) == -1) {
|
2004-03-14 22:44:30 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
2004-04-02 23:21:32 +02:00
|
|
|
break;
|
2012-01-25 23:39:02 +01:00
|
|
|
#ifdef CONFIG_LIBISCSI
|
|
|
|
case QEMU_OPTION_iscsi:
|
|
|
|
opts = qemu_opts_parse(qemu_find_opts("iscsi"), optarg, 0);
|
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
2004-08-24 23:57:12 +02:00
|
|
|
#ifdef CONFIG_SLIRP
|
|
|
|
case QEMU_OPTION_tftp:
|
2009-06-24 14:42:28 +02:00
|
|
|
legacy_tftp_prefix = optarg;
|
2004-08-26 00:12:49 +02:00
|
|
|
break;
|
2007-02-20 01:05:08 +01:00
|
|
|
case QEMU_OPTION_bootp:
|
2009-06-24 14:42:28 +02:00
|
|
|
legacy_bootp_filename = optarg;
|
2007-02-20 01:05:08 +01:00
|
|
|
break;
|
2004-08-26 00:12:49 +02:00
|
|
|
case QEMU_OPTION_redir:
|
Don't exit() in config_error()
Propagating errors up the call chain is tedious. In startup code, we
can take a shortcut: terminate the program. This is wrong elsewhere,
the monitor in particular.
config_error() tries to cater for both customers: it terminates the
program unless its mon parameter tells it it's working for the
monitor.
Its users need to return status anyway (unless passing a null mon
argument, which none do), which their users need to check. So this
automatic exit buys us exactly nothing useful. Only the dangerous
delusion that we can get away without returning status. Some of its
users fell for that. Their callers continue executing after failure
when working for the monitor.
This bites monitor command host_net_add in two places:
* net_slirp_init() continues after slirp_hostfwd(), slirp_guestfwd(),
or slirp_smb() failed, and may end up reporting success. This
happens for "host_net_add user guestfwd=foo": it complains about the
invalid guest forwarding rule, then happily creates the user network
without guest forwarding.
* net_client_init() can't detect slirp_guestfwd() failure, and gets
fooled by net_slirp_init() lying about success. Suppresses its
"Could not initialize device" message.
Add the missing error reporting, make sure errors are checked, and
drop the exit() from config_error().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-10-06 13:16:57 +02:00
|
|
|
if (net_slirp_redir(optarg) < 0)
|
|
|
|
exit(1);
|
2004-08-26 00:12:49 +02:00
|
|
|
break;
|
2004-08-24 23:57:12 +02:00
|
|
|
#endif
|
2008-11-09 01:04:26 +01:00
|
|
|
case QEMU_OPTION_bt:
|
2009-07-15 13:59:26 +02:00
|
|
|
add_device_config(DEV_BT, optarg);
|
2008-11-09 01:04:26 +01:00
|
|
|
break;
|
2005-10-30 19:58:22 +01:00
|
|
|
case QEMU_OPTION_audio_help:
|
|
|
|
AUD_help ();
|
|
|
|
exit (0);
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_soundhw:
|
|
|
|
select_soundhw (optarg);
|
|
|
|
break;
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_h:
|
2007-06-30 01:26:08 +02:00
|
|
|
help(0);
|
2004-05-14 00:02:20 +02:00
|
|
|
break;
|
2009-04-08 00:58:45 +02:00
|
|
|
case QEMU_OPTION_version:
|
|
|
|
version();
|
|
|
|
exit(0);
|
|
|
|
break;
|
2015-01-11 11:38:43 +01:00
|
|
|
case QEMU_OPTION_m:
|
2013-11-27 01:27:35 +01:00
|
|
|
opts = qemu_opts_parse(qemu_find_opts("memory"),
|
|
|
|
optarg, 1);
|
|
|
|
if (!opts) {
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2004-05-14 00:02:20 +02: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 18:47:49 +01: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 00:25:08 +01:00
|
|
|
case QEMU_OPTION_mempath:
|
|
|
|
mem_path = optarg;
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_mem_prealloc:
|
|
|
|
mem_prealloc = 1;
|
|
|
|
break;
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_d:
|
2011-06-07 18:32:40 +02:00
|
|
|
log_mask = optarg;
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_D:
|
|
|
|
log_file = optarg;
|
2004-05-14 00:02:20 +02:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_s:
|
2012-02-07 15:09:13 +01:00
|
|
|
add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT);
|
2004-05-14 00:02:20 +02:00
|
|
|
break;
|
2009-04-05 20:43:41 +02:00
|
|
|
case QEMU_OPTION_gdb:
|
2012-02-07 15:09:13 +01:00
|
|
|
add_device_config(DEV_GDB, optarg);
|
2004-05-14 00:02:20 +02:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_L:
|
2013-03-08 11:42:24 +01:00
|
|
|
if (data_dir_idx < ARRAY_SIZE(data_dir)) {
|
|
|
|
data_dir[data_dir_idx++] = optarg;
|
|
|
|
}
|
2004-05-14 00:02:20 +02:00
|
|
|
break;
|
2007-10-05 15:08:35 +02:00
|
|
|
case QEMU_OPTION_bios:
|
2015-02-12 17:07:34 +01:00
|
|
|
qemu_opts_set(qemu_find_opts("machine"), 0, "firmware", optarg,
|
|
|
|
&error_abort);
|
2007-10-05 15:08:35 +02:00
|
|
|
break;
|
2009-04-05 22:08:59 +02:00
|
|
|
case QEMU_OPTION_singlestep:
|
|
|
|
singlestep = 1;
|
|
|
|
break;
|
2004-05-14 00:02:20 +02:00
|
|
|
case QEMU_OPTION_S:
|
2007-01-21 17:47:01 +01:00
|
|
|
autostart = 0;
|
2004-05-14 00:02:20 +02:00
|
|
|
break;
|
2015-01-11 11:56:51 +01:00
|
|
|
case QEMU_OPTION_k:
|
|
|
|
keyboard_layout = optarg;
|
|
|
|
break;
|
2004-06-03 14:49:50 +02:00
|
|
|
case QEMU_OPTION_localtime:
|
|
|
|
rtc_utc = 0;
|
|
|
|
break;
|
2008-09-28 02:42:05 +02:00
|
|
|
case QEMU_OPTION_vga:
|
2011-09-27 21:15:42 +02:00
|
|
|
vga_model = optarg;
|
2012-05-10 09:39:17 +02:00
|
|
|
default_vga = 0;
|
2004-07-08 23:17:50 +02:00
|
|
|
break;
|
2004-06-21 18:46:10 +02: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:
|
|
|
|
fprintf(stderr, "qemu: invalid resolution or depth\n");
|
|
|
|
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);
|
2007-09-16 23:08:06 +02:00
|
|
|
if (depth != 8 && depth != 15 && depth != 16 &&
|
2004-06-21 18:46:10 +02:00
|
|
|
depth != 24 && depth != 32)
|
|
|
|
goto graphic_error;
|
|
|
|
} else if (*p == '\0') {
|
|
|
|
depth = graphic_depth;
|
|
|
|
} else {
|
|
|
|
goto graphic_error;
|
|
|
|
}
|
2007-09-17 10:09:54 +02:00
|
|
|
|
2004-06-21 18:46:10 +02:00
|
|
|
graphic_width = w;
|
|
|
|
graphic_height = h;
|
|
|
|
graphic_depth = depth;
|
|
|
|
}
|
|
|
|
break;
|
2007-02-18 18:04:49 +01: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 19:28:13 +02:00
|
|
|
case QEMU_OPTION_monitor:
|
2009-12-08 13:11:52 +01:00
|
|
|
default_monitor = 0;
|
2013-05-16 18:02:55 +02:00
|
|
|
if (strncmp(optarg, "none", 4)) {
|
2014-11-17 13:31:04 +01:00
|
|
|
monitor_parse(optarg, "readline", false);
|
2013-05-16 18:02:55 +02:00
|
|
|
}
|
2009-12-08 13:11:52 +01:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_qmp:
|
2014-11-17 13:31:04 +01:00
|
|
|
monitor_parse(optarg, "control", false);
|
|
|
|
default_monitor = 0;
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_qmp_pretty:
|
|
|
|
monitor_parse(optarg, "control", true);
|
2010-03-21 20:14:38 +01:00
|
|
|
default_monitor = 0;
|
2004-07-14 19:28:13 +02:00
|
|
|
break;
|
2009-12-08 13:11:51 +01:00
|
|
|
case QEMU_OPTION_mon:
|
2010-08-20 13:52:01 +02:00
|
|
|
opts = qemu_opts_parse(qemu_find_opts("mon"), optarg, 1);
|
2009-12-08 13:11:51 +01:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2010-03-21 20:14:38 +01:00
|
|
|
default_monitor = 0;
|
2009-12-08 13:11:51 +01:00
|
|
|
break;
|
2009-09-10 10:58:35 +02:00
|
|
|
case QEMU_OPTION_chardev:
|
2010-08-20 13:52:01 +02:00
|
|
|
opts = qemu_opts_parse(qemu_find_opts("chardev"), optarg, 1);
|
2009-09-10 10:58:35 +02:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2010-04-29 14:14:43 +02:00
|
|
|
case QEMU_OPTION_fsdev:
|
2010-08-20 13:52:02 +02:00
|
|
|
olist = qemu_find_opts("fsdev");
|
|
|
|
if (!olist) {
|
|
|
|
fprintf(stderr, "fsdev is not supported by this qemu build.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
opts = qemu_opts_parse(olist, optarg, 1);
|
2010-04-29 14:14:43 +02: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 14:15:03 +02:00
|
|
|
case QEMU_OPTION_virtfs: {
|
2011-03-16 09:31:43 +01:00
|
|
|
QemuOpts *fsdev;
|
|
|
|
QemuOpts *device;
|
2011-12-14 09:28:47 +01:00
|
|
|
const char *writeout, *sock_fd, *socket;
|
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 14:15:03 +02:00
|
|
|
|
2010-08-20 13:52:02 +02:00
|
|
|
olist = qemu_find_opts("virtfs");
|
|
|
|
if (!olist) {
|
|
|
|
fprintf(stderr, "virtfs is not supported by this qemu build.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
opts = qemu_opts_parse(olist, optarg, 1);
|
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 14:15:03 +02:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2011-10-13 08:58:04 +02:00
|
|
|
if (qemu_opt_get(opts, "fsdriver") == NULL ||
|
2011-12-14 09:18:59 +01:00
|
|
|
qemu_opt_get(opts, "mount_tag") == NULL) {
|
|
|
|
fprintf(stderr, "Usage: -virtfs fsdriver,mount_tag=tag.\n");
|
2010-06-14 22:34:40 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
2011-03-16 09:31:43 +01:00
|
|
|
fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
|
2012-03-20 19:51:57 +01:00
|
|
|
qemu_opt_get(opts, "mount_tag"),
|
|
|
|
1, NULL);
|
2011-03-16 09:31:43 +01:00
|
|
|
if (!fsdev) {
|
|
|
|
fprintf(stderr, "duplicate fsdev id: %s\n",
|
|
|
|
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 14:15:03 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
2011-10-12 15:41:23 +02:00
|
|
|
|
|
|
|
writeout = qemu_opt_get(opts, "writeout");
|
|
|
|
if (writeout) {
|
|
|
|
#ifdef CONFIG_SYNC_FILE_RANGE
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(fsdev, "writeout", writeout, &error_abort);
|
2011-10-12 15:41:23 +02:00
|
|
|
#else
|
|
|
|
fprintf(stderr, "writeout=immediate not supported on "
|
|
|
|
"this platform\n");
|
|
|
|
exit(1);
|
|
|
|
#endif
|
|
|
|
}
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(fsdev, "fsdriver",
|
|
|
|
qemu_opt_get(opts, "fsdriver"), &error_abort);
|
|
|
|
qemu_opt_set(fsdev, "path", qemu_opt_get(opts, "path"),
|
|
|
|
&error_abort);
|
2011-03-16 09:31:43 +01:00
|
|
|
qemu_opt_set(fsdev, "security_model",
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_get(opts, "security_model"),
|
|
|
|
&error_abort);
|
2011-12-14 09:28:47 +01:00
|
|
|
socket = qemu_opt_get(opts, "socket");
|
|
|
|
if (socket) {
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(fsdev, "socket", socket, &error_abort);
|
2011-12-14 09:28:47 +01:00
|
|
|
}
|
2011-12-14 09:19:28 +01:00
|
|
|
sock_fd = qemu_opt_get(opts, "sock_fd");
|
|
|
|
if (sock_fd) {
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(fsdev, "sock_fd", sock_fd, &error_abort);
|
2011-12-14 09:19:28 +01:00
|
|
|
}
|
2011-03-16 09:31:43 +01:00
|
|
|
|
2011-10-25 08:40:39 +02:00
|
|
|
qemu_opt_set_bool(fsdev, "readonly",
|
2015-02-12 16:37:44 +01:00
|
|
|
qemu_opt_get_bool(opts, "readonly", 0),
|
|
|
|
&error_abort);
|
2014-01-02 03:49:17 +01:00
|
|
|
device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
|
|
|
|
&error_abort);
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(device, "driver", "virtio-9p-pci", &error_abort);
|
2011-03-16 09:31:43 +01:00
|
|
|
qemu_opt_set(device, "fsdev",
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_get(opts, "mount_tag"), &error_abort);
|
2011-03-16 09:31:43 +01:00
|
|
|
qemu_opt_set(device, "mount_tag",
|
2015-02-12 17:52:20 +01: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 14:15:03 +02:00
|
|
|
break;
|
|
|
|
}
|
2011-10-25 08:40:40 +02:00
|
|
|
case QEMU_OPTION_virtfs_synth: {
|
|
|
|
QemuOpts *fsdev;
|
|
|
|
QemuOpts *device;
|
|
|
|
|
2012-03-20 19:51:57 +01:00
|
|
|
fsdev = qemu_opts_create(qemu_find_opts("fsdev"), "v_synth",
|
|
|
|
1, NULL);
|
2011-10-25 08:40:40 +02:00
|
|
|
if (!fsdev) {
|
|
|
|
fprintf(stderr, "duplicate option: %s\n", "virtfs_synth");
|
|
|
|
exit(1);
|
|
|
|
}
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(fsdev, "fsdriver", "synth", &error_abort);
|
2011-10-25 08:40:40 +02:00
|
|
|
|
2014-01-02 03:49:17 +01:00
|
|
|
device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
|
|
|
|
&error_abort);
|
2015-02-12 17:52:20 +01:00
|
|
|
qemu_opt_set(device, "driver", "virtio-9p-pci", &error_abort);
|
|
|
|
qemu_opt_set(device, "fsdev", "v_synth", &error_abort);
|
|
|
|
qemu_opt_set(device, "mount_tag", "v_synth", &error_abort);
|
2011-10-25 08:40:40 +02:00
|
|
|
break;
|
|
|
|
}
|
2004-07-14 19:28:13 +02:00
|
|
|
case QEMU_OPTION_serial:
|
2009-12-08 13:11:41 +01:00
|
|
|
add_device_config(DEV_SERIAL, optarg);
|
|
|
|
default_serial = 0;
|
2010-03-07 11:28:40 +01:00
|
|
|
if (strncmp(optarg, "mon:", 4) == 0) {
|
|
|
|
default_monitor = 0;
|
|
|
|
}
|
2004-07-14 19:28:13 +02:00
|
|
|
break;
|
2009-04-25 14:56:19 +02:00
|
|
|
case QEMU_OPTION_watchdog:
|
2009-08-21 10:31:34 +02:00
|
|
|
if (watchdog) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"qemu: only one watchdog option may be given\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
watchdog = optarg;
|
2009-04-25 14:56:19 +02:00
|
|
|
break;
|
|
|
|
case QEMU_OPTION_watchdog_action:
|
|
|
|
if (select_watchdog_action(optarg) == -1) {
|
|
|
|
fprintf(stderr, "Unknown -watchdog-action parameter\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2009-01-15 21:06:40 +01:00
|
|
|
case QEMU_OPTION_virtiocon:
|
2009-12-08 13:11:53 +01:00
|
|
|
add_device_config(DEV_VIRTCON, optarg);
|
|
|
|
default_virtcon = 0;
|
2010-03-07 11:28:40 +01:00
|
|
|
if (strncmp(optarg, "mon:", 4) == 0) {
|
|
|
|
default_monitor = 0;
|
|
|
|
}
|
2009-01-15 21:06:40 +01:00
|
|
|
break;
|
2005-01-15 13:02:56 +01:00
|
|
|
case QEMU_OPTION_parallel:
|
2009-12-08 13:11:42 +01:00
|
|
|
add_device_config(DEV_PARALLEL, optarg);
|
|
|
|
default_parallel = 0;
|
2010-03-07 11:28:40 +01:00
|
|
|
if (strncmp(optarg, "mon:", 4) == 0) {
|
|
|
|
default_monitor = 0;
|
|
|
|
}
|
2005-01-15 13:02:56 +01: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-29 22:51:36 +01:00
|
|
|
case QEMU_OPTION_debugcon:
|
|
|
|
add_device_config(DEV_DEBUGCON, optarg);
|
|
|
|
break;
|
2015-01-11 11:56:51 +01:00
|
|
|
case QEMU_OPTION_loadvm:
|
|
|
|
loadvm = optarg;
|
|
|
|
break;
|
2004-10-03 15:29:03 +02:00
|
|
|
case QEMU_OPTION_full_screen:
|
|
|
|
full_screen = 1;
|
|
|
|
break;
|
2007-02-18 19:19:32 +01:00
|
|
|
case QEMU_OPTION_no_frame:
|
|
|
|
no_frame = 1;
|
|
|
|
break;
|
2007-06-21 23:08:02 +02:00
|
|
|
case QEMU_OPTION_alt_grab:
|
|
|
|
alt_grab = 1;
|
|
|
|
break;
|
2009-09-17 22:48:04 +02:00
|
|
|
case QEMU_OPTION_ctrl_grab:
|
|
|
|
ctrl_grab = 1;
|
|
|
|
break;
|
2006-12-11 03:08:05 +01:00
|
|
|
case QEMU_OPTION_no_quit:
|
|
|
|
no_quit = 1;
|
|
|
|
break;
|
2009-01-15 23:14:11 +01:00
|
|
|
case QEMU_OPTION_sdl:
|
2013-06-15 12:44:20 +02:00
|
|
|
#ifdef CONFIG_SDL
|
2009-05-21 23:54:00 +02:00
|
|
|
display_type = DT_SDL;
|
2009-01-15 23:14:11 +01:00
|
|
|
break;
|
2011-03-16 13:33:34 +01:00
|
|
|
#else
|
|
|
|
fprintf(stderr, "SDL support is disabled\n");
|
|
|
|
exit(1);
|
2006-12-11 03:08:05 +01:00
|
|
|
#endif
|
2004-12-08 23:21:25 +01:00
|
|
|
case QEMU_OPTION_pidfile:
|
2007-03-19 16:58:31 +01:00
|
|
|
pid_file = optarg;
|
2004-12-08 23:21:25 +01:00
|
|
|
break;
|
2005-04-30 18:10:35 +02:00
|
|
|
case QEMU_OPTION_win2k_hack:
|
|
|
|
win2k_install_hack = 1;
|
|
|
|
break;
|
2012-01-23 20:15:12 +01:00
|
|
|
case QEMU_OPTION_rtc_td_hack: {
|
|
|
|
static GlobalProperty slew_lost_ticks[] = {
|
|
|
|
{
|
|
|
|
.driver = "mc146818rtc",
|
|
|
|
.property = "lost_tick_policy",
|
|
|
|
.value = "slew",
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
};
|
|
|
|
|
|
|
|
qdev_prop_register_global_list(slew_lost_ticks);
|
2009-01-15 21:11:34 +01:00
|
|
|
break;
|
2012-01-23 20:15:12 +01:00
|
|
|
}
|
2009-02-27 21:12:36 +01:00
|
|
|
case QEMU_OPTION_acpitable:
|
2013-03-21 00:23:17 +01:00
|
|
|
opts = qemu_opts_parse(qemu_find_opts("acpi"), optarg, 1);
|
2013-11-28 18:12:59 +01:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-03-21 00:23:17 +01:00
|
|
|
do_acpitable_option(opts);
|
2009-02-27 21:12:36 +01: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 20:59:56 +02:00
|
|
|
case QEMU_OPTION_smbios:
|
2013-08-16 15:18:29 +02:00
|
|
|
opts = qemu_opts_parse(qemu_find_opts("smbios"), optarg, 0);
|
2013-11-28 18:12:59 +01:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-08-16 15:18:29 +02:00
|
|
|
do_smbios_option(opts);
|
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 20:59:56 +02:00
|
|
|
break;
|
2015-04-29 17:21:53 +02:00
|
|
|
case QEMU_OPTION_fwcfg:
|
|
|
|
opts = qemu_opts_parse(qemu_find_opts("fw_cfg"), optarg, 1);
|
|
|
|
if (opts == NULL) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2008-11-05 17:04:33 +01:00
|
|
|
case QEMU_OPTION_enable_kvm:
|
2010-09-21 21:05:31 +02:00
|
|
|
olist = qemu_find_opts("machine");
|
|
|
|
qemu_opts_parse(olist, "accel=kvm", 0);
|
|
|
|
break;
|
2015-01-07 13:11:38 +01:00
|
|
|
case QEMU_OPTION_M:
|
2010-09-21 21:05:31 +02:00
|
|
|
case QEMU_OPTION_machine:
|
|
|
|
olist = qemu_find_opts("machine");
|
2011-07-23 12:38:37 +02:00
|
|
|
opts = qemu_opts_parse(olist, optarg, 1);
|
2010-09-21 21:05:31 +02:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2008-11-05 17:04:33 +01:00
|
|
|
break;
|
2012-10-05 19:51:45 +02:00
|
|
|
case QEMU_OPTION_no_kvm:
|
|
|
|
olist = qemu_find_opts("machine");
|
|
|
|
qemu_opts_parse(olist, "accel=tcg", 0);
|
|
|
|
break;
|
2012-10-05 19:51:41 +02:00
|
|
|
case QEMU_OPTION_no_kvm_pit: {
|
|
|
|
fprintf(stderr, "Warning: KVM PIT can no longer be disabled "
|
|
|
|
"separately.\n");
|
|
|
|
break;
|
|
|
|
}
|
2012-10-05 19:51:42 +02:00
|
|
|
case QEMU_OPTION_no_kvm_pit_reinjection: {
|
|
|
|
static GlobalProperty kvm_pit_lost_tick_policy[] = {
|
|
|
|
{
|
|
|
|
.driver = "kvm-pit",
|
|
|
|
.property = "lost_tick_policy",
|
|
|
|
.value = "discard",
|
|
|
|
},
|
|
|
|
{ /* end of list */ }
|
|
|
|
};
|
|
|
|
|
|
|
|
fprintf(stderr, "Warning: option deprecated, use "
|
|
|
|
"lost_tick_policy property of kvm-pit instead.\n");
|
|
|
|
qdev_prop_register_global_list(kvm_pit_lost_tick_policy);
|
|
|
|
break;
|
|
|
|
}
|
2005-11-05 15:22:28 +01:00
|
|
|
case QEMU_OPTION_usb:
|
2012-11-22 17:48:45 +01:00
|
|
|
olist = qemu_find_opts("machine");
|
|
|
|
qemu_opts_parse(olist, "usb=on", 0);
|
2005-11-05 15:22:28 +01:00
|
|
|
break;
|
2005-11-06 17:13:29 +01:00
|
|
|
case QEMU_OPTION_usbdevice:
|
2012-11-22 17:48:45 +01:00
|
|
|
olist = qemu_find_opts("machine");
|
|
|
|
qemu_opts_parse(olist, "usb=on", 0);
|
2009-07-15 13:59:26 +02:00
|
|
|
add_device_config(DEV_USB, optarg);
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_device:
|
2010-08-20 13:52:01 +02:00
|
|
|
if (!qemu_opts_parse(qemu_find_opts("device"), optarg, 1)) {
|
2009-07-31 12:25:37 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
2005-11-06 17:13:29 +01:00
|
|
|
break;
|
2005-11-22 00:25:50 +01:00
|
|
|
case QEMU_OPTION_smp:
|
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 13:06:52 +02:00
|
|
|
if (!qemu_opts_parse(qemu_find_opts("smp-opts"), optarg, 1)) {
|
2009-07-23 17:03:42 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
2005-11-22 00:25:50 +01:00
|
|
|
break;
|
2015-01-11 11:56:51 +01:00
|
|
|
case QEMU_OPTION_vnc:
|
2011-03-16 13:33:36 +01:00
|
|
|
#ifdef CONFIG_VNC
|
2014-09-16 12:33:03 +02:00
|
|
|
if (vnc_parse_func(optarg) == NULL) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2011-03-16 13:33:36 +01:00
|
|
|
#else
|
|
|
|
fprintf(stderr, "VNC support is disabled\n");
|
|
|
|
exit(1);
|
|
|
|
#endif
|
|
|
|
break;
|
2006-05-04 00:02:44 +02:00
|
|
|
case QEMU_OPTION_no_acpi:
|
|
|
|
acpi_enabled = 0;
|
|
|
|
break;
|
2008-12-18 00:28:44 +01:00
|
|
|
case QEMU_OPTION_no_hpet:
|
|
|
|
no_hpet = 1;
|
|
|
|
break;
|
2009-06-26 19:15:14 +02:00
|
|
|
case QEMU_OPTION_balloon:
|
|
|
|
if (balloon_parse(optarg) < 0) {
|
|
|
|
fprintf(stderr, "Unknown -balloon argument %s\n", optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
2009-06-10 21:34:08 +02:00
|
|
|
break;
|
2006-10-02 21:44:22 +02:00
|
|
|
case QEMU_OPTION_no_reboot:
|
|
|
|
no_reboot = 1;
|
|
|
|
break;
|
2008-04-11 23:35:52 +02:00
|
|
|
case QEMU_OPTION_no_shutdown:
|
|
|
|
no_shutdown = 1;
|
|
|
|
break;
|
2007-05-01 03:34:14 +02:00
|
|
|
case QEMU_OPTION_show_cursor:
|
|
|
|
cursor_hide = 0;
|
|
|
|
break;
|
2008-09-18 20:29:08 +02:00
|
|
|
case QEMU_OPTION_uuid:
|
|
|
|
if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
|
|
|
|
fprintf(stderr, "Fail to parse UUID string."
|
|
|
|
" Wrong format.\n");
|
|
|
|
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 15:18:31 +02:00
|
|
|
qemu_uuid_set = true;
|
2008-09-18 20:29:08 +02:00
|
|
|
break;
|
2015-01-11 11:56:51 +01:00
|
|
|
case QEMU_OPTION_option_rom:
|
|
|
|
if (nb_option_roms >= MAX_OPTION_ROMS) {
|
|
|
|
fprintf(stderr, "Too many option ROMs\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2010-12-08 12:35:07 +01:00
|
|
|
opts = qemu_opts_parse(qemu_find_opts("option-rom"), optarg, 1);
|
2013-02-08 21:22:19 +01:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2010-12-08 12:35:07 +01: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) {
|
|
|
|
fprintf(stderr, "Option ROM file is not specified\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2015-01-11 11:56:51 +01:00
|
|
|
nb_option_roms++;
|
|
|
|
break;
|
2007-01-20 18:12:09 +01:00
|
|
|
case QEMU_OPTION_semihosting:
|
|
|
|
semihosting_enabled = 1;
|
2014-12-11 13:07:48 +01:00
|
|
|
semihosting_target = SEMIHOSTING_TARGET_AUTO;
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_semihosting_config:
|
|
|
|
semihosting_enabled = 1;
|
|
|
|
opts = qemu_opts_parse(qemu_find_opts("semihosting-config"),
|
|
|
|
optarg, 0);
|
|
|
|
if (opts != NULL) {
|
|
|
|
semihosting_enabled = qemu_opt_get_bool(opts, "enable",
|
|
|
|
true);
|
|
|
|
const char *target = qemu_opt_get(opts, "target");
|
|
|
|
if (target != NULL) {
|
|
|
|
if (strcmp("native", target) == 0) {
|
|
|
|
semihosting_target = SEMIHOSTING_TARGET_NATIVE;
|
|
|
|
} else if (strcmp("gdb", target) == 0) {
|
|
|
|
semihosting_target = SEMIHOSTING_TARGET_GDB;
|
|
|
|
} else if (strcmp("auto", target) == 0) {
|
|
|
|
semihosting_target = SEMIHOSTING_TARGET_AUTO;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Unsupported semihosting-config"
|
|
|
|
" %s\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
semihosting_target = SEMIHOSTING_TARGET_AUTO;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Unsupported semihosting-config %s\n",
|
|
|
|
optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
2007-01-20 18:12:09 +01:00
|
|
|
break;
|
2012-10-05 19:51:44 +02:00
|
|
|
case QEMU_OPTION_tdf:
|
|
|
|
fprintf(stderr, "Warning: user space PIT time drift fix "
|
|
|
|
"is no longer supported.\n");
|
|
|
|
break;
|
2007-03-19 16:17:08 +01:00
|
|
|
case QEMU_OPTION_name:
|
2014-01-30 11:20:30 +01:00
|
|
|
opts = qemu_opts_parse(qemu_find_opts("name"), optarg, 1);
|
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2007-03-19 16:17:08 +01:00
|
|
|
break;
|
2007-05-01 16:16:52 +02:00
|
|
|
case QEMU_OPTION_prom_env:
|
|
|
|
if (nb_prom_envs >= MAX_PROM_ENVS) {
|
|
|
|
fprintf(stderr, "Too many prom variables\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
prom_envs[nb_prom_envs] = optarg;
|
|
|
|
nb_prom_envs++;
|
|
|
|
break;
|
2007-07-28 00:08:46 +02:00
|
|
|
case QEMU_OPTION_old_param:
|
|
|
|
old_param = 1;
|
2008-01-08 20:32:16 +01:00
|
|
|
break;
|
2007-08-24 03:26:02 +02:00
|
|
|
case QEMU_OPTION_clock:
|
2013-08-21 17:02:59 +02:00
|
|
|
/* Clock options no longer exist. Keep this option for
|
|
|
|
* backward compatibility.
|
|
|
|
*/
|
2007-08-24 03:26:02 +02:00
|
|
|
break;
|
2007-11-07 17:24:33 +01:00
|
|
|
case QEMU_OPTION_startdate:
|
2009-09-15 13:36:04 +02:00
|
|
|
configure_rtc_date_offset(optarg, 1);
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_rtc:
|
2010-08-20 13:52:01 +02:00
|
|
|
opts = qemu_opts_parse(qemu_find_opts("rtc"), optarg, 0);
|
2009-09-15 13:36:04 +02:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
2007-11-07 17:24:33 +01:00
|
|
|
}
|
2009-09-15 13:36:04 +02:00
|
|
|
configure_rtc(opts);
|
2007-11-07 17:24:33 +01:00
|
|
|
break;
|
2008-05-28 14:30:31 +02:00
|
|
|
case QEMU_OPTION_tb_size:
|
2011-08-02 16:10:21 +02:00
|
|
|
tcg_tb_size = strtol(optarg, NULL, 0);
|
|
|
|
if (tcg_tb_size < 0) {
|
|
|
|
tcg_tb_size = 0;
|
|
|
|
}
|
2008-05-28 14:30:31 +02:00
|
|
|
break;
|
2008-06-29 03:03:05 +02:00
|
|
|
case QEMU_OPTION_icount:
|
2014-07-25 11:56:28 +02:00
|
|
|
icount_opts = qemu_opts_parse(qemu_find_opts("icount"),
|
|
|
|
optarg, 1);
|
|
|
|
if (!icount_opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2008-06-29 03:03:05 +02:00
|
|
|
break;
|
2008-10-13 05:12:02 +02:00
|
|
|
case QEMU_OPTION_incoming:
|
2015-02-26 15:16:06 +01:00
|
|
|
if (!incoming) {
|
|
|
|
runstate_set(RUN_STATE_INMIGRATE);
|
|
|
|
}
|
2008-10-13 05:12:02 +02:00
|
|
|
incoming = optarg;
|
|
|
|
break;
|
2009-12-08 13:11:46 +01:00
|
|
|
case QEMU_OPTION_nodefaults:
|
2014-03-10 15:37:40 +01:00
|
|
|
has_defaults = 0;
|
2009-12-08 13:11:46 +01:00
|
|
|
break;
|
2009-04-22 17:19:10 +02:00
|
|
|
case QEMU_OPTION_xen_domid:
|
2010-03-29 21:23:52 +02:00
|
|
|
if (!(xen_available())) {
|
|
|
|
printf("Option %s not supported for this target\n", popt->name);
|
|
|
|
exit(1);
|
|
|
|
}
|
2009-04-22 17:19:10 +02:00
|
|
|
xen_domid = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_xen_create:
|
2010-03-29 21:23:52 +02:00
|
|
|
if (!(xen_available())) {
|
|
|
|
printf("Option %s not supported for this target\n", popt->name);
|
|
|
|
exit(1);
|
|
|
|
}
|
2009-04-22 17:19:10 +02:00
|
|
|
xen_mode = XEN_CREATE;
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_xen_attach:
|
2010-03-29 21:23:52 +02:00
|
|
|
if (!(xen_available())) {
|
|
|
|
printf("Option %s not supported for this target\n", popt->name);
|
|
|
|
exit(1);
|
|
|
|
}
|
2009-04-22 17:19:10 +02:00
|
|
|
xen_mode = XEN_ATTACH;
|
|
|
|
break;
|
2010-08-09 12:48:32 +02:00
|
|
|
case QEMU_OPTION_trace:
|
2011-08-31 20:31:03 +02:00
|
|
|
{
|
2010-08-09 12:48:32 +02:00
|
|
|
opts = qemu_opts_parse(qemu_find_opts("trace"), optarg, 0);
|
2011-08-31 20:31:03 +02:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
2010-08-09 12:48:32 +02:00
|
|
|
}
|
2011-08-31 20:31:31 +02:00
|
|
|
trace_events = qemu_opt_get(opts, "events");
|
2011-08-31 20:31:03 +02:00
|
|
|
trace_file = qemu_opt_get(opts, "file");
|
2010-08-09 12:48:32 +02:00
|
|
|
break;
|
2011-08-31 20:31:03 +02:00
|
|
|
}
|
2009-10-14 10:39:28 +02:00
|
|
|
case QEMU_OPTION_readconfig:
|
|
|
|
{
|
2010-03-05 17:25:55 +01:00
|
|
|
int ret = qemu_read_config_file(optarg);
|
|
|
|
if (ret < 0) {
|
|
|
|
fprintf(stderr, "read config %s: %s\n", optarg,
|
|
|
|
strerror(-ret));
|
2009-10-14 10:39:28 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2010-03-11 15:13:27 +01:00
|
|
|
case QEMU_OPTION_spice:
|
|
|
|
olist = qemu_find_opts("spice");
|
|
|
|
if (!olist) {
|
|
|
|
fprintf(stderr, "spice is not supported by this qemu build.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
opts = qemu_opts_parse(olist, optarg, 0);
|
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-02-25 16:02:30 +01:00
|
|
|
display_remote++;
|
2010-03-11 15:13:27 +01:00
|
|
|
break;
|
2009-10-14 10:39:28 +02:00
|
|
|
case QEMU_OPTION_writeconfig:
|
|
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
if (strcmp(optarg, "-") == 0) {
|
|
|
|
fp = stdout;
|
|
|
|
} else {
|
|
|
|
fp = fopen(optarg, "w");
|
|
|
|
if (fp == NULL) {
|
|
|
|
fprintf(stderr, "open %s: %s\n", optarg, strerror(errno));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
qemu_config_write(fp);
|
2014-04-22 03:12:34 +02:00
|
|
|
if (fp != stdout) {
|
|
|
|
fclose(fp);
|
|
|
|
}
|
2009-10-14 10:39:28 +02:00
|
|
|
break;
|
|
|
|
}
|
2012-03-28 15:42:02 +02:00
|
|
|
case QEMU_OPTION_qtest:
|
|
|
|
qtest_chrdev = optarg;
|
|
|
|
break;
|
|
|
|
case QEMU_OPTION_qtest_log:
|
|
|
|
qtest_log = optarg;
|
|
|
|
break;
|
2012-08-14 23:44:08 +02:00
|
|
|
case QEMU_OPTION_sandbox:
|
|
|
|
opts = qemu_opts_parse(qemu_find_opts("sandbox"), optarg, 1);
|
|
|
|
if (!opts) {
|
2013-02-08 21:22:19 +01:00
|
|
|
exit(1);
|
2012-08-14 23:44:08 +02:00
|
|
|
}
|
|
|
|
break;
|
2012-10-18 21:19:34 +02:00
|
|
|
case QEMU_OPTION_add_fd:
|
|
|
|
#ifndef _WIN32
|
|
|
|
opts = qemu_opts_parse(qemu_find_opts("add-fd"), optarg, 0);
|
|
|
|
if (!opts) {
|
2013-02-08 21:22:19 +01:00
|
|
|
exit(1);
|
2012-10-18 21:19:34 +02:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
error_report("File descriptor passing is disabled on this "
|
|
|
|
"platform");
|
|
|
|
exit(1);
|
|
|
|
#endif
|
|
|
|
break;
|
2012-06-25 21:36:33 +02:00
|
|
|
case QEMU_OPTION_object:
|
|
|
|
opts = qemu_opts_parse(qemu_find_opts("object"), optarg, 1);
|
2013-02-08 21:22:19 +01:00
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2012-06-25 21:36:33 +02:00
|
|
|
break;
|
2013-04-19 16:42:06 +02:00
|
|
|
case QEMU_OPTION_realtime:
|
|
|
|
opts = qemu_opts_parse(qemu_find_opts("realtime"), optarg, 0);
|
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2014-09-23 12:42:24 +02:00
|
|
|
enable_mlock = qemu_opt_get_bool(opts, "mlock", true);
|
2013-04-19 16:42:06 +02:00
|
|
|
break;
|
2013-07-04 05:02:46 +02:00
|
|
|
case QEMU_OPTION_msg:
|
|
|
|
opts = qemu_opts_parse(qemu_find_opts("msg"), optarg, 0);
|
|
|
|
if (!opts) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
configure_msg(opts);
|
|
|
|
break;
|
2014-06-20 15:26:08 +02:00
|
|
|
case QEMU_OPTION_dump_vmstate:
|
2014-10-29 13:49:43 +01:00
|
|
|
if (vmstate_dump_file) {
|
|
|
|
fprintf(stderr, "qemu: only one '-dump-vmstate' "
|
|
|
|
"option may be given\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2014-06-20 15:26:08 +02:00
|
|
|
vmstate_dump_file = fopen(optarg, "w");
|
|
|
|
if (vmstate_dump_file == NULL) {
|
|
|
|
fprintf(stderr, "open %s: %s\n", optarg, strerror(errno));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2010-06-10 11:42:25 +02:00
|
|
|
default:
|
|
|
|
os_parse_cmd_args(popt->index, optarg);
|
2004-05-14 00:02:20 +02:00
|
|
|
}
|
2003-06-24 15:42:40 +02:00
|
|
|
}
|
|
|
|
}
|
2015-01-07 13:11:38 +01:00
|
|
|
|
|
|
|
opts = qemu_get_machine_opts();
|
|
|
|
optarg = qemu_opt_get(opts, "type");
|
|
|
|
if (optarg) {
|
|
|
|
machine_class = machine_parse(optarg);
|
|
|
|
}
|
|
|
|
|
2015-05-07 07:33:57 +02:00
|
|
|
if (machine_class == NULL) {
|
|
|
|
fprintf(stderr, "No machine specified, and there is no default.\n"
|
|
|
|
"Use -machine help to list supported machines!\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
set_memory_options(&ram_slots, &maxram_size, machine_class);
|
2015-01-11 11:38:43 +01:00
|
|
|
|
2010-02-18 20:13:51 +01:00
|
|
|
loc_set_none();
|
2011-06-07 18:32:40 +02:00
|
|
|
|
2014-06-02 15:25:00 +02:00
|
|
|
os_daemonize();
|
|
|
|
|
2014-09-18 13:30:49 +02:00
|
|
|
if (qemu_init_main_loop(&main_loop_err)) {
|
2015-02-12 13:55:05 +01:00
|
|
|
error_report_err(main_loop_err);
|
2012-10-30 00:17:12 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("sandbox"),
|
|
|
|
parse_sandbox, NULL, NULL)) {
|
2012-08-14 23:44:08 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("name"),
|
|
|
|
parse_name, NULL, NULL)) {
|
2014-05-06 13:15:55 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2012-10-18 21:19:34 +02:00
|
|
|
#ifndef _WIN32
|
2015-03-13 13:35:14 +01:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("add-fd"),
|
|
|
|
parse_add_fd, NULL, NULL)) {
|
2012-10-18 21:19:34 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("add-fd"),
|
|
|
|
cleanup_add_fd, NULL, NULL)) {
|
2012-10-18 21:19:34 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-03-05 18:30:47 +01:00
|
|
|
current_machine = MACHINE(object_new(object_class_get_name(
|
|
|
|
OBJECT_CLASS(machine_class))));
|
2014-12-16 17:58:06 +01:00
|
|
|
if (machine_help_func(qemu_get_machine_opts(), current_machine)) {
|
|
|
|
exit(0);
|
|
|
|
}
|
2014-03-05 18:30:47 +01:00
|
|
|
object_property_add_child(object_get_root(), "machine",
|
|
|
|
OBJECT(current_machine), &error_abort);
|
2014-06-11 10:52:32 +02:00
|
|
|
cpu_exec_init_all();
|
2014-03-05 18:30:47 +01:00
|
|
|
|
2014-04-09 19:34:53 +02:00
|
|
|
if (machine_class->hw_version) {
|
|
|
|
qemu_set_version(machine_class->hw_version);
|
2012-05-30 05:35:51 +02:00
|
|
|
}
|
|
|
|
|
2012-03-09 20:19:07 +01:00
|
|
|
/* Init CPU def lists, based on config
|
|
|
|
* - Must be called after all the qemu_read_config_file() calls
|
|
|
|
* - Must be called before list_cpus()
|
|
|
|
* - Must be called before machine->init()
|
|
|
|
*/
|
|
|
|
cpudef_init();
|
|
|
|
|
2012-08-02 14:45:54 +02:00
|
|
|
if (cpu_model && is_help_option(cpu_model)) {
|
2012-03-21 13:33:40 +01:00
|
|
|
list_cpus(stdout, &fprintf, cpu_model);
|
2012-03-09 20:19:07 +01:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2015-06-10 16:20:24 +02:00
|
|
|
/* Open the logfile at this point and set the log mask if necessary.
|
2011-06-07 18:32:40 +02:00
|
|
|
*/
|
2015-06-10 16:20:24 +02:00
|
|
|
if (log_file) {
|
|
|
|
qemu_set_log_filename(log_file);
|
|
|
|
}
|
|
|
|
|
2011-06-07 18:32:40 +02:00
|
|
|
if (log_mask) {
|
2013-02-11 17:41:24 +01:00
|
|
|
int mask;
|
|
|
|
mask = qemu_str_to_log_mask(log_mask);
|
|
|
|
if (!mask) {
|
|
|
|
qemu_print_log_usage(stdout);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
qemu_set_log(mask);
|
2011-06-07 18:32:40 +02:00
|
|
|
}
|
2003-07-26 20:11:40 +02:00
|
|
|
|
2013-09-23 16:36:54 +02:00
|
|
|
if (!is_daemonized()) {
|
2014-05-27 15:02:14 +02:00
|
|
|
if (!trace_init_backends(trace_events, trace_file)) {
|
2013-09-23 16:36:54 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
2011-03-13 21:14:30 +01:00
|
|
|
}
|
2011-02-26 19:38:39 +01:00
|
|
|
|
2009-05-30 01:52:44 +02:00
|
|
|
/* If no data_dir is specified then try to find it relative to the
|
|
|
|
executable path. */
|
2013-03-08 11:42:24 +01:00
|
|
|
if (data_dir_idx < ARRAY_SIZE(data_dir)) {
|
2014-02-10 07:48:51 +01:00
|
|
|
data_dir[data_dir_idx] = os_find_datadir();
|
2013-03-08 11:42:24 +01:00
|
|
|
if (data_dir[data_dir_idx] != NULL) {
|
|
|
|
data_dir_idx++;
|
|
|
|
}
|
2009-05-30 01:52:44 +02:00
|
|
|
}
|
2011-09-04 15:17:46 +02:00
|
|
|
/* If all else fails use the install path specified when building. */
|
2013-03-08 11:42:24 +01:00
|
|
|
if (data_dir_idx < ARRAY_SIZE(data_dir)) {
|
|
|
|
data_dir[data_dir_idx++] = CONFIG_QEMU_DATADIR;
|
2009-05-30 01:52:44 +02:00
|
|
|
}
|
|
|
|
|
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 13:06:52 +02:00
|
|
|
smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
|
2009-07-23 17:03:42 +02:00
|
|
|
|
2014-04-09 19:34:53 +02:00
|
|
|
machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
|
2014-12-19 03:59:46 +01:00
|
|
|
if (max_cpus > machine_class->max_cpus) {
|
2008-10-07 22:39:39 +02:00
|
|
|
fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
|
2014-12-19 03:59:46 +01:00
|
|
|
"supported by machine `%s' (%d)\n", max_cpus,
|
2014-04-09 19:34:53 +02:00
|
|
|
machine_class->name, machine_class->max_cpus);
|
2008-10-07 22:39:39 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2010-11-22 16:44:15 +01:00
|
|
|
/*
|
|
|
|
* Get the default machine options from the machine if it is not already
|
|
|
|
* specified either by the configuration file or by the command line.
|
|
|
|
*/
|
2014-04-09 19:34:53 +02:00
|
|
|
if (machine_class->default_machine_opts) {
|
2012-01-27 19:55:43 +01:00
|
|
|
qemu_opts_set_defaults(qemu_find_opts("machine"),
|
2014-04-09 19:34:53 +02:00
|
|
|
machine_class->default_machine_opts, 0);
|
2010-11-22 16:44:15 +01:00
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
qemu_opts_foreach(qemu_find_opts("device"),
|
|
|
|
default_driver_check, NULL, NULL);
|
|
|
|
qemu_opts_foreach(qemu_find_opts("global"),
|
|
|
|
default_driver_check, NULL, NULL);
|
2009-12-08 13:11:41 +01:00
|
|
|
|
2014-03-10 15:37:40 +01:00
|
|
|
if (!vga_model && !default_vga) {
|
|
|
|
vga_interface_type = VGA_DEVICE;
|
|
|
|
}
|
2014-04-09 19:34:53 +02:00
|
|
|
if (!has_defaults || machine_class->no_serial) {
|
2009-12-08 13:11:54 +01:00
|
|
|
default_serial = 0;
|
|
|
|
}
|
2014-04-09 19:34:53 +02:00
|
|
|
if (!has_defaults || machine_class->no_parallel) {
|
2009-12-08 13:11:54 +01:00
|
|
|
default_parallel = 0;
|
|
|
|
}
|
2014-04-09 19:34:53 +02:00
|
|
|
if (!has_defaults || !machine_class->use_virtcon) {
|
2009-12-08 13:11:54 +01:00
|
|
|
default_virtcon = 0;
|
|
|
|
}
|
2014-04-09 19:34:53 +02:00
|
|
|
if (!has_defaults || !machine_class->use_sclp) {
|
2013-01-24 12:18:52 +01:00
|
|
|
default_sclp = 0;
|
|
|
|
}
|
2014-04-09 19:34:53 +02:00
|
|
|
if (!has_defaults || machine_class->no_floppy) {
|
2009-12-16 14:25:39 +01:00
|
|
|
default_floppy = 0;
|
|
|
|
}
|
2014-04-09 19:34:53 +02:00
|
|
|
if (!has_defaults || machine_class->no_cdrom) {
|
2009-12-16 14:25:39 +01:00
|
|
|
default_cdrom = 0;
|
|
|
|
}
|
2014-04-09 19:34:53 +02:00
|
|
|
if (!has_defaults || machine_class->no_sdcard) {
|
2009-12-16 14:25:39 +01:00
|
|
|
default_sdcard = 0;
|
|
|
|
}
|
2014-03-10 15:37:40 +01:00
|
|
|
if (!has_defaults) {
|
|
|
|
default_monitor = 0;
|
|
|
|
default_net = 0;
|
|
|
|
default_vga = 0;
|
|
|
|
}
|
2009-12-08 13:11:54 +01:00
|
|
|
|
disallow -daemonize usage of stdio (curses display, -nographic, -serial stdio etc)
Curses display requires stdin/out to stay on the terminal,
so -daemonize makes no sense in this case. Instead of
leaving display uninitialized like is done since 995ee2bf469de6bb,
explicitly detect this case earlier and error out.
-nographic can actually be used with -daemonize, by redirecting
everything to a null device, but the problem is that according
to documentation and historical behavour, -nographic redirects
guest ports to stdin/out, which, again, makes no sense in case
of -daemonize. Since -nographic is a legacy option, don't bother
fixing this case (to allow -nographic and -daemonize by redirecting
guest ports to null instead of stdin/out in this case), but disallow
it completely instead, to stop garbling host terminal.
If no display display needed and user wants to use -nographic,
the right way to go is to use
-serial null -parallel null -monitor none -display none -vga none
instead of -nographic.
Also prevent the same issue -- it was possible to get garbled
host tty after
-nographic -daemonize
and it is still possible to have it by using
-serial stdio -daemonize
Fix this by disallowing opening stdio chardev when -daemonize
is specified.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-12-30 09:48:14 +01: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 (display_type == DT_NOGRAPHIC
|
|
|
|
&& (default_parallel || default_serial
|
|
|
|
|| default_monitor || default_virtcon)) {
|
|
|
|
fprintf(stderr, "-nographic can not be used with -daemonize\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
#ifdef CONFIG_CURSES
|
|
|
|
if (display_type == DT_CURSES) {
|
|
|
|
fprintf(stderr, "curses display can not be used with -daemonize\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2009-05-21 23:54:00 +02:00
|
|
|
if (display_type == DT_NOGRAPHIC) {
|
2009-12-08 13:11:42 +01:00
|
|
|
if (default_parallel)
|
|
|
|
add_device_config(DEV_PARALLEL, "null");
|
2009-12-08 13:11:44 +01:00
|
|
|
if (default_serial && default_monitor) {
|
|
|
|
add_device_config(DEV_SERIAL, "mon:stdio");
|
2009-12-08 13:11:54 +01:00
|
|
|
} else if (default_virtcon && default_monitor) {
|
|
|
|
add_device_config(DEV_VIRTCON, "mon:stdio");
|
2013-01-24 12:18:52 +01:00
|
|
|
} else if (default_sclp && default_monitor) {
|
|
|
|
add_device_config(DEV_SCLP, "mon:stdio");
|
2009-12-08 13:11:44 +01:00
|
|
|
} else {
|
|
|
|
if (default_serial)
|
|
|
|
add_device_config(DEV_SERIAL, "stdio");
|
2009-12-08 13:11:54 +01:00
|
|
|
if (default_virtcon)
|
|
|
|
add_device_config(DEV_VIRTCON, "stdio");
|
2013-01-24 12:18:52 +01:00
|
|
|
if (default_sclp) {
|
|
|
|
add_device_config(DEV_SCLP, "stdio");
|
|
|
|
}
|
2009-12-08 13:11:44 +01:00
|
|
|
if (default_monitor)
|
2014-11-17 13:31:04 +01:00
|
|
|
monitor_parse("stdio", "readline", false);
|
2009-12-08 13:11:44 +01:00
|
|
|
}
|
2009-12-08 13:11:41 +01:00
|
|
|
} else {
|
|
|
|
if (default_serial)
|
|
|
|
add_device_config(DEV_SERIAL, "vc:80Cx24C");
|
2009-12-08 13:11:42 +01:00
|
|
|
if (default_parallel)
|
|
|
|
add_device_config(DEV_PARALLEL, "vc:80Cx24C");
|
2009-12-08 13:11:43 +01:00
|
|
|
if (default_monitor)
|
2014-11-17 13:31:04 +01:00
|
|
|
monitor_parse("vc:80Cx24C", "readline", false);
|
2009-12-17 13:06:08 +01:00
|
|
|
if (default_virtcon)
|
|
|
|
add_device_config(DEV_VIRTCON, "vc:80Cx24C");
|
2013-01-24 12:18:52 +01:00
|
|
|
if (default_sclp) {
|
|
|
|
add_device_config(DEV_SCLP, "vc:80Cx24C");
|
|
|
|
}
|
2008-08-01 17:12:34 +02:00
|
|
|
}
|
|
|
|
|
2015-02-17 08:45:06 +01:00
|
|
|
#if defined(CONFIG_VNC)
|
|
|
|
if (!QTAILQ_EMPTY(&(qemu_find_opts("vnc")->head))) {
|
|
|
|
display_remote++;
|
|
|
|
}
|
|
|
|
#endif
|
2013-02-20 14:43:25 +01:00
|
|
|
if (display_type == DT_DEFAULT && !display_remote) {
|
|
|
|
#if defined(CONFIG_GTK)
|
|
|
|
display_type = DT_GTK;
|
|
|
|
#elif defined(CONFIG_SDL) || defined(CONFIG_COCOA)
|
|
|
|
display_type = DT_SDL;
|
|
|
|
#elif defined(CONFIG_VNC)
|
2014-09-16 12:33:03 +02:00
|
|
|
vnc_parse_func("localhost:0,to=99,id=default");
|
2013-02-20 14:43:25 +01:00
|
|
|
show_vnc_port = 1;
|
|
|
|
#else
|
|
|
|
display_type = DT_NONE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-06-11 10:55:08 +02:00
|
|
|
if ((no_frame || alt_grab || ctrl_grab) && display_type != DT_SDL) {
|
|
|
|
fprintf(stderr, "-no-frame, -alt-grab and -ctrl-grab are only valid "
|
|
|
|
"for SDL, ignoring option\n");
|
|
|
|
}
|
|
|
|
if (no_quit && (display_type != DT_GTK && display_type != DT_SDL)) {
|
|
|
|
fprintf(stderr, "-no-quit is only valid for GTK and SDL, "
|
|
|
|
"ignoring option\n");
|
|
|
|
}
|
|
|
|
|
2013-02-20 14:43:25 +01:00
|
|
|
#if defined(CONFIG_GTK)
|
|
|
|
if (display_type == DT_GTK) {
|
2015-01-20 12:43:28 +01:00
|
|
|
early_gtk_display_init(request_opengl);
|
2013-02-20 14:43:25 +01:00
|
|
|
}
|
|
|
|
#endif
|
2014-11-11 16:54:45 +01:00
|
|
|
#if defined(CONFIG_SDL)
|
|
|
|
if (display_type == DT_SDL) {
|
|
|
|
sdl_display_early_init(request_opengl);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (request_opengl == 1 && display_opengl == 0) {
|
|
|
|
#if defined(CONFIG_OPENGL)
|
|
|
|
fprintf(stderr, "OpenGL is not supported by the display.\n");
|
|
|
|
#else
|
|
|
|
fprintf(stderr, "QEMU was built without opengl support.\n");
|
|
|
|
#endif
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-02-20 14:43:25 +01:00
|
|
|
|
2010-04-15 06:37:55 +02:00
|
|
|
socket_init();
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("chardev"),
|
|
|
|
chardev_init_func, NULL, NULL)) {
|
2009-12-08 13:11:36 +01:00
|
|
|
exit(1);
|
2015-03-13 11:07:24 +01:00
|
|
|
}
|
|
|
|
|
2010-06-14 22:34:41 +02:00
|
|
|
#ifdef CONFIG_VIRTFS
|
2015-03-13 13:35:14 +01:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("fsdev"),
|
|
|
|
fsdev_init_func, NULL, NULL)) {
|
2010-04-29 14:14:43 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
#endif
|
2009-12-08 13:11:36 +01:00
|
|
|
|
2007-03-25 23:33:06 +02:00
|
|
|
if (pid_file && qemu_create_pidfile(pid_file) != 0) {
|
2014-10-30 15:40:48 +01:00
|
|
|
fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno));
|
2007-03-19 16:58:31 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("device"),
|
|
|
|
device_help_func, NULL, NULL)) {
|
2012-08-09 20:47:40 +02:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("object"),
|
|
|
|
object_create, NULL, NULL)) {
|
2014-08-25 13:47:00 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2014-05-26 14:40:58 +02:00
|
|
|
machine_opts = qemu_get_machine_opts();
|
2015-03-12 08:40:25 +01:00
|
|
|
if (qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
|
|
|
|
NULL)) {
|
2014-05-26 14:40:58 +02:00
|
|
|
object_unref(OBJECT(current_machine));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2014-09-26 22:45:30 +02:00
|
|
|
configure_accelerator(current_machine);
|
2009-09-18 07:41:23 +02:00
|
|
|
|
2013-10-18 13:51:11 +02:00
|
|
|
if (qtest_chrdev) {
|
2014-02-10 02:28:02 +01:00
|
|
|
Error *local_err = NULL;
|
|
|
|
qtest_init(qtest_chrdev, qtest_log, &local_err);
|
|
|
|
if (local_err) {
|
2015-02-12 13:55:05 +01:00
|
|
|
error_report_err(local_err);
|
2014-02-10 02:28:02 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
2013-04-15 21:28:17 +02:00
|
|
|
}
|
|
|
|
|
2013-07-04 15:09:22 +02:00
|
|
|
machine_opts = qemu_get_machine_opts();
|
|
|
|
kernel_filename = qemu_opt_get(machine_opts, "kernel");
|
|
|
|
initrd_filename = qemu_opt_get(machine_opts, "initrd");
|
|
|
|
kernel_cmdline = qemu_opt_get(machine_opts, "append");
|
2013-10-15 16:57:45 +02:00
|
|
|
bios_name = qemu_opt_get(machine_opts, "firmware");
|
2012-02-22 23:40:00 +01:00
|
|
|
|
vl: Fix -boot order and once regressions, and related bugs
Option "once" sets up a different boot order just for the initial
boot. Boot order reverts back to normal on reset. Option "order"
changes the normal boot order.
The reversal is implemented by reset handler restore_boot_devices(),
which takes the boot order to revert to as argument.
restore_boot_devices() does nothing on its first call, because that
must be the initial machine reset. On its second call, it changes the
boot order back, and unregisters itself.
Because we register the handler right when -boot gets parsed, we can
revert to an incorrect normal boot order, and multiple -boot can
interact in funny ways.
Here's how things work without -boot once or order:
* boot_devices is "".
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "". machine->init() configures firmware
accordingly. For PC machines, machine->boot_order is "cad", and
pc_cmos_init() writes it to RTC CMOS, where SeaBIOS picks it up.
Now consider -boot order=:
* boot_devices is "".
* -boot order= sets boot_devices to "" (no change).
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "", as above.
Bug: -boot order= has no effect. Broken in commit e4ada29e.
Next, consider -boot once=a:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* main() passes boot_devices "a" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "a".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of machine->boot_order. The
actual boot order depends on how firmware interprets "". Broken
in commit e4ada29e.
Next, consider -boot once=a -boot order=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot order=c sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "c".
Bug: it should be "a". I figure this has always been broken.
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of "c". I figure this has
always been broken, just differently broken before commit
e4ada29e.
Next, consider -boot once=a -boot once=b -boot once=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot once=b registers restore_boot_devices() with argument "a", and
sets boot_devices to "b".
* -boot once=c registers restore_boot_devices() with argument "b", and
sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
- restore_boot_devices() gets called with argument "a". Calls
qemu_boot_set("a") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
- restore_boot_devices() gets called with argument "b". Calls
qemu_boot_set("b") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
* Machine boots, boot order is "b".
Bug: should really be "c", because that came last, and for all other
-boot options, the last one wins. I figure this was broken some
time before commit 37905d6a, and fixed there only for a single
occurence of "once".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Same bug as above: boot order reverts to "" instead of
machine->boot_order.
Fix by acting upon -boot options order, once and menu only after
option parsing is complete, and the machine is known. This is how the
other -boot options work already.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1371208516-7857-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-14 13:15:03 +02:00
|
|
|
opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL);
|
|
|
|
if (opts) {
|
2014-12-03 18:11:39 +01:00
|
|
|
Error *local_err = NULL;
|
vl: Fix -boot order and once regressions, and related bugs
Option "once" sets up a different boot order just for the initial
boot. Boot order reverts back to normal on reset. Option "order"
changes the normal boot order.
The reversal is implemented by reset handler restore_boot_devices(),
which takes the boot order to revert to as argument.
restore_boot_devices() does nothing on its first call, because that
must be the initial machine reset. On its second call, it changes the
boot order back, and unregisters itself.
Because we register the handler right when -boot gets parsed, we can
revert to an incorrect normal boot order, and multiple -boot can
interact in funny ways.
Here's how things work without -boot once or order:
* boot_devices is "".
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "". machine->init() configures firmware
accordingly. For PC machines, machine->boot_order is "cad", and
pc_cmos_init() writes it to RTC CMOS, where SeaBIOS picks it up.
Now consider -boot order=:
* boot_devices is "".
* -boot order= sets boot_devices to "" (no change).
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "", as above.
Bug: -boot order= has no effect. Broken in commit e4ada29e.
Next, consider -boot once=a:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* main() passes boot_devices "a" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "a".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of machine->boot_order. The
actual boot order depends on how firmware interprets "". Broken
in commit e4ada29e.
Next, consider -boot once=a -boot order=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot order=c sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "c".
Bug: it should be "a". I figure this has always been broken.
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of "c". I figure this has
always been broken, just differently broken before commit
e4ada29e.
Next, consider -boot once=a -boot once=b -boot once=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot once=b registers restore_boot_devices() with argument "a", and
sets boot_devices to "b".
* -boot once=c registers restore_boot_devices() with argument "b", and
sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
- restore_boot_devices() gets called with argument "a". Calls
qemu_boot_set("a") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
- restore_boot_devices() gets called with argument "b". Calls
qemu_boot_set("b") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
* Machine boots, boot order is "b".
Bug: should really be "c", because that came last, and for all other
-boot options, the last one wins. I figure this was broken some
time before commit 37905d6a, and fixed there only for a single
occurence of "once".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Same bug as above: boot order reverts to "" instead of
machine->boot_order.
Fix by acting upon -boot options order, once and menu only after
option parsing is complete, and the machine is known. This is how the
other -boot options work already.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1371208516-7857-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-14 13:15:03 +02:00
|
|
|
|
2015-02-03 12:31:09 +01:00
|
|
|
boot_order = qemu_opt_get(opts, "order");
|
|
|
|
if (boot_order) {
|
|
|
|
validate_bootdevices(boot_order, &local_err);
|
2014-12-03 18:11:39 +01:00
|
|
|
if (local_err) {
|
2015-02-12 13:55:05 +01:00
|
|
|
error_report_err(local_err);
|
2014-12-03 18:11:39 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
vl: Fix -boot order and once regressions, and related bugs
Option "once" sets up a different boot order just for the initial
boot. Boot order reverts back to normal on reset. Option "order"
changes the normal boot order.
The reversal is implemented by reset handler restore_boot_devices(),
which takes the boot order to revert to as argument.
restore_boot_devices() does nothing on its first call, because that
must be the initial machine reset. On its second call, it changes the
boot order back, and unregisters itself.
Because we register the handler right when -boot gets parsed, we can
revert to an incorrect normal boot order, and multiple -boot can
interact in funny ways.
Here's how things work without -boot once or order:
* boot_devices is "".
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "". machine->init() configures firmware
accordingly. For PC machines, machine->boot_order is "cad", and
pc_cmos_init() writes it to RTC CMOS, where SeaBIOS picks it up.
Now consider -boot order=:
* boot_devices is "".
* -boot order= sets boot_devices to "" (no change).
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "", as above.
Bug: -boot order= has no effect. Broken in commit e4ada29e.
Next, consider -boot once=a:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* main() passes boot_devices "a" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "a".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of machine->boot_order. The
actual boot order depends on how firmware interprets "". Broken
in commit e4ada29e.
Next, consider -boot once=a -boot order=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot order=c sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "c".
Bug: it should be "a". I figure this has always been broken.
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of "c". I figure this has
always been broken, just differently broken before commit
e4ada29e.
Next, consider -boot once=a -boot once=b -boot once=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot once=b registers restore_boot_devices() with argument "a", and
sets boot_devices to "b".
* -boot once=c registers restore_boot_devices() with argument "b", and
sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
- restore_boot_devices() gets called with argument "a". Calls
qemu_boot_set("a") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
- restore_boot_devices() gets called with argument "b". Calls
qemu_boot_set("b") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
* Machine boots, boot order is "b".
Bug: should really be "c", because that came last, and for all other
-boot options, the last one wins. I figure this was broken some
time before commit 37905d6a, and fixed there only for a single
occurence of "once".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Same bug as above: boot order reverts to "" instead of
machine->boot_order.
Fix by acting upon -boot options order, once and menu only after
option parsing is complete, and the machine is known. This is how the
other -boot options work already.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1371208516-7857-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-14 13:15:03 +02:00
|
|
|
}
|
|
|
|
|
2015-02-03 12:31:09 +01:00
|
|
|
boot_once = qemu_opt_get(opts, "once");
|
|
|
|
if (boot_once) {
|
|
|
|
validate_bootdevices(boot_once, &local_err);
|
2014-12-03 18:11:39 +01:00
|
|
|
if (local_err) {
|
2015-02-12 13:55:05 +01:00
|
|
|
error_report_err(local_err);
|
2014-12-03 18:11:39 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
vl: Fix -boot order and once regressions, and related bugs
Option "once" sets up a different boot order just for the initial
boot. Boot order reverts back to normal on reset. Option "order"
changes the normal boot order.
The reversal is implemented by reset handler restore_boot_devices(),
which takes the boot order to revert to as argument.
restore_boot_devices() does nothing on its first call, because that
must be the initial machine reset. On its second call, it changes the
boot order back, and unregisters itself.
Because we register the handler right when -boot gets parsed, we can
revert to an incorrect normal boot order, and multiple -boot can
interact in funny ways.
Here's how things work without -boot once or order:
* boot_devices is "".
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "". machine->init() configures firmware
accordingly. For PC machines, machine->boot_order is "cad", and
pc_cmos_init() writes it to RTC CMOS, where SeaBIOS picks it up.
Now consider -boot order=:
* boot_devices is "".
* -boot order= sets boot_devices to "" (no change).
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "", as above.
Bug: -boot order= has no effect. Broken in commit e4ada29e.
Next, consider -boot once=a:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* main() passes boot_devices "a" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "a".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of machine->boot_order. The
actual boot order depends on how firmware interprets "". Broken
in commit e4ada29e.
Next, consider -boot once=a -boot order=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot order=c sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "c".
Bug: it should be "a". I figure this has always been broken.
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of "c". I figure this has
always been broken, just differently broken before commit
e4ada29e.
Next, consider -boot once=a -boot once=b -boot once=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot once=b registers restore_boot_devices() with argument "a", and
sets boot_devices to "b".
* -boot once=c registers restore_boot_devices() with argument "b", and
sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
- restore_boot_devices() gets called with argument "a". Calls
qemu_boot_set("a") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
- restore_boot_devices() gets called with argument "b". Calls
qemu_boot_set("b") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
* Machine boots, boot order is "b".
Bug: should really be "c", because that came last, and for all other
-boot options, the last one wins. I figure this was broken some
time before commit 37905d6a, and fixed there only for a single
occurence of "once".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Same bug as above: boot order reverts to "" instead of
machine->boot_order.
Fix by acting upon -boot options order, once and menu only after
option parsing is complete, and the machine is known. This is how the
other -boot options work already.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1371208516-7857-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-14 13:15:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
boot_menu = qemu_opt_get_bool(opts, "menu", boot_menu);
|
2013-12-09 12:53:15 +01:00
|
|
|
boot_strict = qemu_opt_get_bool(opts, "strict", false);
|
vl: Fix -boot order and once regressions, and related bugs
Option "once" sets up a different boot order just for the initial
boot. Boot order reverts back to normal on reset. Option "order"
changes the normal boot order.
The reversal is implemented by reset handler restore_boot_devices(),
which takes the boot order to revert to as argument.
restore_boot_devices() does nothing on its first call, because that
must be the initial machine reset. On its second call, it changes the
boot order back, and unregisters itself.
Because we register the handler right when -boot gets parsed, we can
revert to an incorrect normal boot order, and multiple -boot can
interact in funny ways.
Here's how things work without -boot once or order:
* boot_devices is "".
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "". machine->init() configures firmware
accordingly. For PC machines, machine->boot_order is "cad", and
pc_cmos_init() writes it to RTC CMOS, where SeaBIOS picks it up.
Now consider -boot order=:
* boot_devices is "".
* -boot order= sets boot_devices to "" (no change).
* main() passes machine->boot_order to to machine->init(), because
boot_devices is "", as above.
Bug: -boot order= has no effect. Broken in commit e4ada29e.
Next, consider -boot once=a:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* main() passes boot_devices "a" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "a".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of machine->boot_order. The
actual boot order depends on how firmware interprets "". Broken
in commit e4ada29e.
Next, consider -boot once=a -boot order=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot order=c sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
* Machine boots, boot order is "c".
Bug: it should be "a". I figure this has always been broken.
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Bug: boot order reverts to "" instead of "c". I figure this has
always been broken, just differently broken before commit
e4ada29e.
Next, consider -boot once=a -boot once=b -boot once=c:
* boot_devices is "".
* -boot once=a registers restore_boot_devices() with argument "", and
sets boot_devices to "a".
* -boot once=b registers restore_boot_devices() with argument "a", and
sets boot_devices to "b".
* -boot once=c registers restore_boot_devices() with argument "b", and
sets boot_devices to "c".
* main() passes boot_devices "c" to machine->init(), which configures
firmware accordingly. For PC machines, pc_cmos_init() writes the
boot order to RTC CMOS.
* main() calls qemu_system_reset(). This runs reset handlers.
- restore_boot_devices() gets called with argument "". Does
nothing, because it's the first call.
- restore_boot_devices() gets called with argument "a". Calls
qemu_boot_set("a") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
- restore_boot_devices() gets called with argument "b". Calls
qemu_boot_set("b") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
* Machine boots, boot order is "b".
Bug: should really be "c", because that came last, and for all other
-boot options, the last one wins. I figure this was broken some
time before commit 37905d6a, and fixed there only for a single
occurence of "once".
* Machine resets (e.g. monitor command). Reset handlers run.
- restore_boot_devices() gets called with argument "". Calls
qemu_boot_set("") to reconfigure firmware. For PC machines,
pc_boot_set() writes it into RTC CMOS. Reset handler
unregistered.
Same bug as above: boot order reverts to "" instead of
machine->boot_order.
Fix by acting upon -boot options order, once and menu only after
option parsing is complete, and the machine is known. This is how the
other -boot options work already.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Message-id: 1371208516-7857-4-git-send-email-armbru@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2013-06-14 13:15:03 +02:00
|
|
|
}
|
|
|
|
|
2015-02-03 12:31:09 +01:00
|
|
|
if (!boot_order) {
|
|
|
|
boot_order = machine_class->default_boot_order;
|
|
|
|
}
|
|
|
|
|
2012-02-08 06:41:39 +01:00
|
|
|
if (!kernel_cmdline) {
|
|
|
|
kernel_cmdline = "";
|
2014-05-26 14:40:58 +02:00
|
|
|
current_machine->kernel_cmdline = (char *)kernel_cmdline;
|
2012-02-08 06:41:39 +01:00
|
|
|
}
|
|
|
|
|
2003-09-30 23:07:02 +02:00
|
|
|
linux_boot = (kernel_filename != NULL);
|
2007-11-17 13:12:29 +01:00
|
|
|
|
2008-07-03 12:01:15 +02:00
|
|
|
if (!linux_boot && *kernel_cmdline != '\0') {
|
|
|
|
fprintf(stderr, "-append only allowed with -kernel option\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!linux_boot && initrd_filename != NULL) {
|
|
|
|
fprintf(stderr, "-initrd only allowed with -kernel option\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2013-07-04 15:09:22 +02:00
|
|
|
if (!linux_boot && qemu_opt_get(machine_opts, "dtb")) {
|
2012-03-02 12:56:38 +01:00
|
|
|
fprintf(stderr, "-dtb only allowed with -kernel option\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2010-06-10 11:42:30 +02:00
|
|
|
os_set_line_buffering();
|
2007-09-17 10:09:54 +02:00
|
|
|
|
2012-03-14 19:33:37 +01:00
|
|
|
#ifdef CONFIG_SPICE
|
|
|
|
/* spice needs the timers to be initialized by this point */
|
|
|
|
qemu_spice_init();
|
|
|
|
#endif
|
|
|
|
|
2014-09-01 07:34:49 +02:00
|
|
|
cpu_ticks_init();
|
2014-07-25 11:56:28 +02:00
|
|
|
if (icount_opts) {
|
|
|
|
if (kvm_enabled() || xen_enabled()) {
|
|
|
|
fprintf(stderr, "-icount is not allowed with kvm or xen\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
configure_icount(icount_opts, &error_abort);
|
|
|
|
qemu_opts_del(icount_opts);
|
2011-11-10 12:38:42 +01:00
|
|
|
}
|
2006-07-15 19:40:09 +02:00
|
|
|
|
2012-12-11 15:20:15 +01:00
|
|
|
/* clean up network at qemu process termination */
|
|
|
|
atexit(&net_cleanup);
|
|
|
|
|
2009-10-06 13:17:16 +02:00
|
|
|
if (net_init_clients() < 0) {
|
|
|
|
exit(1);
|
2004-04-02 23:21:32 +02:00
|
|
|
}
|
2003-06-25 02:07:40 +02:00
|
|
|
|
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 18:47:49 +01:00
|
|
|
#ifdef CONFIG_TPM
|
|
|
|
if (tpm_init() < 0) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-11-09 01:04:26 +01:00
|
|
|
/* init the bluetooth world */
|
2009-07-15 13:59:26 +02:00
|
|
|
if (foreach_device_config(DEV_BT, bt_parse))
|
|
|
|
exit(1);
|
2008-11-09 01:04:26 +01:00
|
|
|
|
2011-07-20 10:17:44 +02:00
|
|
|
if (!xen_enabled()) {
|
|
|
|
/* On 32-bit hosts, QEMU is limited by virtual address space */
|
|
|
|
if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
|
|
|
|
fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
2007-01-05 18:39:04 +01:00
|
|
|
|
2009-11-02 14:40:58 +01:00
|
|
|
blk_mig_init();
|
2014-03-19 19:32:30 +01:00
|
|
|
ram_mig_init();
|
2009-11-02 14:40:58 +01:00
|
|
|
|
pc/vl: Add units-per-default-bus property
This patch adds the 'units_per_default_bus' property which
allows individual boards to declare their desired
index => (bus,unit) mapping for their default HBA, so that
boards such as Q35 can specify that its default if_ide HBA,
AHCI, only accepts one unit per bus.
This property only overrides the mapping for drives matching
the block_default_type interface.
This patch also adds this property to *all* past and present
Q35 machine types. This retroactive addition is justified
because the previous erroneous index=>(bus,unit) mappings
caused by lack of such a property were not utilized due to
lack of initialization code in the Q35 init routine.
Further, semantically, the Q35 board type has always had the
property that its default HBA, AHCI, only accepts one unit per
bus. The new code added to add devices to drives relies upon
the accuracy of this mapping. Thus, the property is applied
retroactively to reduce complexity of allowing IDE HBAs with
different units per bus.
Examples:
Prior to this patch, all IDE HBAs were assumed to use 2 units
per bus (Master, Slave). When using Q35 and AHCI, however, we
only allow one unit per bus.
-hdb foo.qcow2 would become index=1, or bus=0,unit=1.
-hdd foo.qcow2 would become index=3, or bus=1,unit=1.
-drive file=foo.qcow2,index=5 becomes bus=2,unit=1.
These are invalid for AHCI. They now become, under Q35 only:
-hdb foo.qcow2 --> index=1, bus=1, unit=0.
-hdd foo.qcow2 --> index=3, bus=3, unit=0.
-drive file=foo.qcow2,index=5 --> bus=5,unit=0.
The mapping is adjusted based on the fact that the default IF
for the Q35 machine type is IF_IDE, and units-per-default-bus
overrides the IDE mapping from its default of 2 units per bus
to just 1 unit per bus.
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-id: 1412187569-23452-4-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-01 20:19:26 +02:00
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2007-12-02 05:51:10 +01:00
|
|
|
/* open the virtual block devices */
|
2009-07-22 16:43:04 +02:00
|
|
|
if (snapshot)
|
2015-03-13 13:35:14 +01:00
|
|
|
qemu_opts_foreach(qemu_find_opts("drive"),
|
|
|
|
drive_enable_snapshot, NULL, NULL);
|
2012-11-20 15:30:34 +01:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func,
|
2015-03-13 13:35:14 +01:00
|
|
|
&machine_class->block_default_type, NULL)) {
|
2009-07-22 16:43:04 +02:00
|
|
|
exit(1);
|
2012-11-20 15:30:34 +01:00
|
|
|
}
|
2007-04-30 04:09:25 +02:00
|
|
|
|
2014-04-09 19:34:53 +02:00
|
|
|
default_drive(default_cdrom, snapshot, machine_class->block_default_type, 2,
|
2012-11-22 21:02:55 +01:00
|
|
|
CDROM_OPTS);
|
|
|
|
default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS);
|
|
|
|
default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS);
|
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 11:21:45 +01:00
|
|
|
|
2015-03-19 18:09:21 +01:00
|
|
|
parse_numa_opts(machine_class);
|
2009-04-22 00:30:27 +02:00
|
|
|
|
2015-03-13 13:35:14 +01:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("mon"),
|
|
|
|
mon_init_func, NULL, NULL)) {
|
2010-04-06 16:55:53 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2009-12-08 13:11:41 +01:00
|
|
|
if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
|
|
|
|
exit(1);
|
2009-12-08 13:11:42 +01:00
|
|
|
if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
|
|
|
|
exit(1);
|
2009-12-08 13:11:53 +01:00
|
|
|
if (foreach_device_config(DEV_VIRTCON, virtcon_parse) < 0)
|
|
|
|
exit(1);
|
2013-01-24 12:18:52 +01:00
|
|
|
if (foreach_device_config(DEV_SCLP, sclp_parse) < 0) {
|
|
|
|
exit(1);
|
|
|
|
}
|
debugcon: support for debugging consoles (e.g. Bochs port 0xe9)
Add generic support for debugging consoles (simple I/O ports which
when written to cause debugging output to be written to a target.)
The current implementation matches Bochs' port 0xe9, allowing the same
debugging code to be used for both Bochs and Qemu.
There is no vm state associated with the debugging port, simply
because it has none -- the entire interface is a single, stateless,
write-only port.
Most of the code was cribbed from the serial port driver.
v2: removed non-ISA variants (they can be introduced when/if someone
wants them, using code from the serial port); added configurable
readback (Bochs returns 0xe9 on a read from this register, mimic that
by default) This retains the apparently somewhat controversial user
friendly option, however.
v3: reimplemented the user friendly option as a synthetic option
("-debugcon foo" basically ends up being a parser-level shorthand for
"-chardev stdio,id=debugcon -device isa-debugcon,chardev=debugcon") --
this dramatically reduced the complexity while keeping the same level
of user friendliness.
v4: spaces, not tabs.
v5: update to match current top of tree. Calling qemu_chr_open()
already during parsing no longer works; defer until we are parsing the
other console-like devices.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-29 22:51:36 +01:00
|
|
|
if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
|
|
|
|
exit(1);
|
2009-01-16 21:23:27 +01:00
|
|
|
|
2012-05-10 09:39:17 +02:00
|
|
|
/* If no default VGA is requested, the default is "none". */
|
2012-09-10 01:01:44 +02:00
|
|
|
if (default_vga) {
|
2014-10-28 10:09:11 +01:00
|
|
|
if (machine_class->default_display) {
|
|
|
|
vga_model = machine_class->default_display;
|
|
|
|
} else if (cirrus_vga_available()) {
|
2012-09-10 01:01:44 +02:00
|
|
|
vga_model = "cirrus";
|
|
|
|
} else if (vga_available()) {
|
|
|
|
vga_model = "std";
|
|
|
|
}
|
2011-09-27 21:15:42 +02:00
|
|
|
}
|
2014-03-10 15:37:40 +01:00
|
|
|
if (vga_model) {
|
|
|
|
select_vgahw(vga_model);
|
|
|
|
}
|
2011-09-27 21:15:42 +02:00
|
|
|
|
2009-08-21 10:31:34 +02:00
|
|
|
if (watchdog) {
|
|
|
|
i = select_watchdog(watchdog);
|
|
|
|
if (i > 0)
|
|
|
|
exit (i == 1 ? 1 : 0);
|
|
|
|
}
|
|
|
|
|
2014-04-09 19:34:53 +02:00
|
|
|
if (machine_class->compat_props) {
|
|
|
|
qdev_prop_register_global_list(machine_class->compat_props);
|
2009-07-15 13:48:21 +02:00
|
|
|
}
|
2009-12-08 13:11:34 +01:00
|
|
|
qemu_add_globals();
|
|
|
|
|
2011-12-19 23:37:46 +01:00
|
|
|
qdev_machine_init();
|
|
|
|
|
2014-05-07 16:42:57 +02:00
|
|
|
current_machine->ram_size = ram_size;
|
2014-06-02 15:25:02 +02:00
|
|
|
current_machine->maxram_size = maxram_size;
|
|
|
|
current_machine->ram_slots = ram_slots;
|
2014-05-07 16:42:57 +02:00
|
|
|
current_machine->boot_order = boot_order;
|
|
|
|
current_machine->cpu_model = cpu_model;
|
|
|
|
|
|
|
|
machine_class->init(current_machine);
|
2009-01-16 20:04:14 +01:00
|
|
|
|
2014-09-23 12:42:24 +02:00
|
|
|
realtime_init();
|
|
|
|
|
2013-04-18 18:44:04 +02:00
|
|
|
audio_init();
|
|
|
|
|
2010-03-01 19:10:30 +01:00
|
|
|
cpu_synchronize_all_post_init();
|
2009-04-22 00:30:27 +02:00
|
|
|
|
2015-02-08 19:51:22 +01:00
|
|
|
numa_post_machine_init();
|
2009-04-22 00:30:27 +02:00
|
|
|
|
2015-04-29 17:21:53 +02:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("fw_cfg"),
|
|
|
|
parse_fw_cfg, fw_cfg_find(), NULL) != 0) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2009-01-16 20:04:14 +01:00
|
|
|
/* init USB devices */
|
2015-01-06 14:29:14 +01:00
|
|
|
if (usb_enabled()) {
|
Don't exit() in config_error()
Propagating errors up the call chain is tedious. In startup code, we
can take a shortcut: terminate the program. This is wrong elsewhere,
the monitor in particular.
config_error() tries to cater for both customers: it terminates the
program unless its mon parameter tells it it's working for the
monitor.
Its users need to return status anyway (unless passing a null mon
argument, which none do), which their users need to check. So this
automatic exit buys us exactly nothing useful. Only the dangerous
delusion that we can get away without returning status. Some of its
users fell for that. Their callers continue executing after failure
when working for the monitor.
This bites monitor command host_net_add in two places:
* net_slirp_init() continues after slirp_hostfwd(), slirp_guestfwd(),
or slirp_smb() failed, and may end up reporting success. This
happens for "host_net_add user guestfwd=foo": it complains about the
invalid guest forwarding rule, then happily creates the user network
without guest forwarding.
* net_client_init() can't detect slirp_guestfwd() failure, and gets
fooled by net_slirp_init() lying about success. Suppresses its
"Could not initialize device" message.
Add the missing error reporting, make sure errors are checked, and
drop the exit() from config_error().
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-10-06 13:16:57 +02:00
|
|
|
if (foreach_device_config(DEV_USB, usb_parse) < 0)
|
|
|
|
exit(1);
|
2009-01-16 20:04:14 +01:00
|
|
|
}
|
|
|
|
|
2009-07-15 13:59:26 +02:00
|
|
|
/* init generic devices */
|
2015-03-13 13:35:14 +01:00
|
|
|
if (qemu_opts_foreach(qemu_find_opts("device"),
|
|
|
|
device_init_func, NULL, NULL)) {
|
2009-07-15 13:59:26 +02:00
|
|
|
exit(1);
|
2015-03-13 11:07:24 +01:00
|
|
|
}
|
2009-07-15 13:59:26 +02:00
|
|
|
|
2014-10-01 20:19:24 +02:00
|
|
|
/* Did we create any drives that we failed to create a device for? */
|
|
|
|
drive_check_orphaned();
|
|
|
|
|
2010-02-11 14:44:58 +01:00
|
|
|
net_check_clients();
|
|
|
|
|
2015-02-03 12:31:09 +01:00
|
|
|
if (boot_once) {
|
|
|
|
Error *local_err = NULL;
|
|
|
|
qemu_boot_set(boot_once, &local_err);
|
|
|
|
if (local_err) {
|
|
|
|
error_report("%s", error_get_pretty(local_err));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
qemu_register_reset(restore_boot_order, g_strdup(boot_order));
|
|
|
|
}
|
|
|
|
|
2013-03-07 17:08:29 +01:00
|
|
|
ds = init_displaystate();
|
2009-05-21 23:54:00 +02:00
|
|
|
|
2010-08-25 10:51:06 +02:00
|
|
|
/* init local displays */
|
2009-05-21 23:54:00 +02:00
|
|
|
switch (display_type) {
|
|
|
|
case DT_NOGRAPHIC:
|
2013-10-29 05:36:31 +01:00
|
|
|
(void)ds; /* avoid warning if no display is configured */
|
2009-05-21 23:54:00 +02:00
|
|
|
break;
|
2008-02-10 17:33:14 +01:00
|
|
|
#if defined(CONFIG_CURSES)
|
2009-05-21 23:54:00 +02:00
|
|
|
case DT_CURSES:
|
disallow -daemonize usage of stdio (curses display, -nographic, -serial stdio etc)
Curses display requires stdin/out to stay on the terminal,
so -daemonize makes no sense in this case. Instead of
leaving display uninitialized like is done since 995ee2bf469de6bb,
explicitly detect this case earlier and error out.
-nographic can actually be used with -daemonize, by redirecting
everything to a null device, but the problem is that according
to documentation and historical behavour, -nographic redirects
guest ports to stdin/out, which, again, makes no sense in case
of -daemonize. Since -nographic is a legacy option, don't bother
fixing this case (to allow -nographic and -daemonize by redirecting
guest ports to null instead of stdin/out in this case), but disallow
it completely instead, to stop garbling host terminal.
If no display display needed and user wants to use -nographic,
the right way to go is to use
-serial null -parallel null -monitor none -display none -vga none
instead of -nographic.
Also prevent the same issue -- it was possible to get garbled
host tty after
-nographic -daemonize
and it is still possible to have it by using
-serial stdio -daemonize
Fix this by disallowing opening stdio chardev when -daemonize
is specified.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-12-30 09:48:14 +01:00
|
|
|
curses_display_init(ds, full_screen);
|
2009-05-21 23:54:00 +02:00
|
|
|
break;
|
2008-02-10 17:33:14 +01:00
|
|
|
#endif
|
2005-03-01 22:37:28 +01:00
|
|
|
#if defined(CONFIG_SDL)
|
2009-05-21 23:54:00 +02:00
|
|
|
case DT_SDL:
|
|
|
|
sdl_display_init(ds, full_screen, no_frame);
|
|
|
|
break;
|
2005-03-01 22:37:28 +01:00
|
|
|
#elif defined(CONFIG_COCOA)
|
2009-05-21 23:54:00 +02:00
|
|
|
case DT_SDL:
|
|
|
|
cocoa_display_init(ds, full_screen);
|
|
|
|
break;
|
2013-02-20 14:43:25 +01:00
|
|
|
#endif
|
|
|
|
#if defined(CONFIG_GTK)
|
|
|
|
case DT_GTK:
|
2014-03-12 08:33:50 +01:00
|
|
|
gtk_display_init(ds, full_screen, grab_on_hover);
|
2013-02-20 14:43:25 +01:00
|
|
|
break;
|
2003-08-10 23:52:11 +02:00
|
|
|
#endif
|
2010-08-25 10:51:06 +02:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-03-31 11:27:23 +02:00
|
|
|
/* must be after terminal init, SDL library changes signal handlers */
|
|
|
|
os_setup_signal_handling();
|
|
|
|
|
2011-03-16 13:33:36 +01:00
|
|
|
#ifdef CONFIG_VNC
|
2010-08-25 10:51:06 +02:00
|
|
|
/* init remote displays */
|
2015-03-13 13:35:14 +01:00
|
|
|
qemu_opts_foreach(qemu_find_opts("vnc"),
|
|
|
|
vnc_init_func, NULL, NULL);
|
2014-09-16 12:33:03 +02:00
|
|
|
if (show_vnc_port) {
|
2015-05-25 08:47:25 +02:00
|
|
|
char *ret = vnc_display_local_addr("default");
|
|
|
|
printf("VNC server running on `%s'\n", ret);
|
|
|
|
g_free(ret);
|
2003-08-10 23:52:11 +02:00
|
|
|
}
|
2011-03-16 13:33:36 +01:00
|
|
|
#endif
|
2010-08-25 15:32:06 +02:00
|
|
|
#ifdef CONFIG_SPICE
|
2013-10-11 22:39:59 +02:00
|
|
|
if (using_spice) {
|
|
|
|
qemu_spice_display_init();
|
2010-08-25 15:32:06 +02:00
|
|
|
}
|
|
|
|
#endif
|
2008-08-21 22:08:03 +02:00
|
|
|
|
2012-02-07 15:09:13 +01:00
|
|
|
if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
|
2009-04-05 20:43:41 +02:00
|
|
|
exit(1);
|
2007-07-02 15:20:17 +02:00
|
|
|
}
|
|
|
|
|
2009-09-25 21:42:41 +02:00
|
|
|
qdev_machine_creation_done();
|
|
|
|
|
2009-12-14 16:07:35 +01:00
|
|
|
if (rom_load_all() != 0) {
|
|
|
|
fprintf(stderr, "rom loading failed\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2009-10-01 16:42:33 +02:00
|
|
|
|
2010-12-20 06:33:35 +01:00
|
|
|
/* TODO: once all bus devices are qdevified, this should be done
|
|
|
|
* when bus is created by qdev.c */
|
|
|
|
qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
|
2010-12-08 12:35:08 +01:00
|
|
|
qemu_run_machine_init_done_notifiers();
|
|
|
|
|
2013-07-24 17:56:08 +02:00
|
|
|
/* Done notifiers can load ROMs */
|
|
|
|
rom_load_done();
|
|
|
|
|
2011-06-14 18:29:43 +02:00
|
|
|
qemu_system_reset(VMRESET_SILENT);
|
2009-08-20 19:42:22 +02:00
|
|
|
if (loadvm) {
|
2010-02-17 16:24:10 +01:00
|
|
|
if (load_vmstate(loadvm) < 0) {
|
2009-08-20 19:42:22 +02:00
|
|
|
autostart = 0;
|
|
|
|
}
|
|
|
|
}
|
2004-10-03 15:29:03 +02:00
|
|
|
|
2014-08-08 21:03:30 +02:00
|
|
|
qdev_prop_check_globals();
|
2014-06-20 15:26:08 +02:00
|
|
|
if (vmstate_dump_file) {
|
|
|
|
/* dump and exit */
|
|
|
|
dump_vmstate_json_to_file(vmstate_dump_file);
|
|
|
|
return 0;
|
|
|
|
}
|
2014-05-05 20:03:06 +02:00
|
|
|
|
2009-07-24 22:20:23 +02:00
|
|
|
if (incoming) {
|
2012-10-02 18:21:18 +02:00
|
|
|
Error *local_err = NULL;
|
|
|
|
qemu_start_incoming_migration(incoming, &local_err);
|
|
|
|
if (local_err) {
|
2013-08-05 21:40:44 +02:00
|
|
|
error_report("-incoming %s: %s", incoming,
|
|
|
|
error_get_pretty(local_err));
|
2012-10-02 18:21:18 +02:00
|
|
|
error_free(local_err);
|
|
|
|
exit(1);
|
2010-06-09 14:10:54 +02:00
|
|
|
}
|
2009-08-09 13:39:20 +02:00
|
|
|
} else if (autostart) {
|
2009-03-06 00:01:01 +01:00
|
|
|
vm_start();
|
2009-08-09 13:39:20 +02:00
|
|
|
}
|
2006-12-21 20:46:43 +01:00
|
|
|
|
2010-06-10 11:42:28 +02:00
|
|
|
os_setup_post();
|
2006-12-22 03:11:31 +01:00
|
|
|
|
2013-09-23 16:36:54 +02:00
|
|
|
if (is_daemonized()) {
|
2014-05-27 15:02:14 +02:00
|
|
|
if (!trace_init_backends(trace_events, trace_file)) {
|
2013-09-23 16:36:54 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-03-31 21:00:16 +02:00
|
|
|
main_loop();
|
2011-09-12 14:03:13 +02:00
|
|
|
bdrv_close_all();
|
|
|
|
pause_all_vcpus();
|
2011-07-27 12:04:55 +02:00
|
|
|
res_free();
|
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 18:47:49 +01:00
|
|
|
#ifdef CONFIG_TPM
|
|
|
|
tpm_cleanup();
|
|
|
|
#endif
|
2007-10-22 01:20:45 +02:00
|
|
|
|
2003-06-24 15:42:40 +02:00
|
|
|
return 0;
|
|
|
|
}
|