aboutsummaryrefslogtreecommitdiff
path: root/vl.c
diff options
context:
space:
mode:
authorLinaro Packagers <linaro-pkg@lists.launchpad.net>2013-02-25 10:33:42 +0000
committerFathi Boudra <fathi.boudra@linaro.org>2013-03-30 21:18:26 +0200
commitc3565b8703553405641c76a4c40961473d051edd (patch)
tree01be1a3169d8c72f8e0fd406b81eea561e7f87e7 /vl.c
parentedde41b3c75bce779549bd2e1dba18eb7beb8267 (diff)
parent050a840ead5e51a1a9f3bffe89cc89077b2f35ed (diff)
Imported Debian patch 1.4.0-2013.03-0ubuntu1~linaro1debian/1.4.0-2013.03-0ubuntu1_linaro1
Diffstat (limited to 'vl.c')
-rw-r--r--vl.c572
1 files changed, 449 insertions, 123 deletions
diff --git a/vl.c b/vl.c
index a3ab384..1355f69 100644
--- a/vl.c
+++ b/vl.c
@@ -28,7 +28,7 @@
#include <errno.h>
#include <sys/time.h>
#include <zlib.h>
-#include "bitmap.h"
+#include "qemu/bitmap.h"
/* Needed early for CONFIG_BSD etc. */
#include "config-host.h"
@@ -65,7 +65,7 @@
#endif
#ifdef CONFIG_SECCOMP
-#include "qemu-seccomp.h"
+#include "sysemu/seccomp.h"
#endif
#ifdef __sun__
@@ -126,46 +126,46 @@ int main(int argc, char **argv)
#include "hw/xen.h"
#include "hw/qdev.h"
#include "hw/loader.h"
-#include "bt-host.h"
-#include "net.h"
+#include "bt/bt.h"
+#include "net/net.h"
#include "net/slirp.h"
-#include "monitor.h"
-#include "console.h"
-#include "sysemu.h"
-#include "gdbstub.h"
-#include "qemu-timer.h"
-#include "qemu-char.h"
-#include "cache-utils.h"
-#include "blockdev.h"
+#include "monitor/monitor.h"
+#include "ui/console.h"
+#include "sysemu/sysemu.h"
+#include "exec/gdbstub.h"
+#include "qemu/timer.h"
+#include "char/char.h"
+#include "qemu/cache-utils.h"
+#include "sysemu/blockdev.h"
#include "hw/block-common.h"
-#include "block-migration.h"
-#include "dma.h"
+#include "migration/block.h"
+#include "sysemu/dma.h"
#include "audio/audio.h"
-#include "migration.h"
-#include "kvm.h"
-#include "qjson.h"
-#include "qemu-option.h"
-#include "qemu-config.h"
+#include "migration/migration.h"
+#include "sysemu/kvm.h"
+#include "qapi/qmp/qjson.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
#include "qemu-options.h"
#include "qmp-commands.h"
-#include "main-loop.h"
+#include "qemu/main-loop.h"
#ifdef CONFIG_VIRTFS
#include "fsdev/qemu-fsdev.h"
#endif
-#include "qtest.h"
+#include "sysemu/qtest.h"
-#include "disas.h"
+#include "disas/disas.h"
-#include "qemu_socket.h"
+#include "qemu/sockets.h"
#include "slirp/libslirp.h"
#include "trace.h"
#include "trace/control.h"
-#include "qemu-queue.h"
-#include "cpus.h"
-#include "arch_init.h"
-#include "osdep.h"
+#include "qemu/queue.h"
+#include "sysemu/cpus.h"
+#include "sysemu/arch_init.h"
+#include "qemu/osdep.h"
#include "ui/qemu-spice.h"
#include "qapi/string-input-visitor.h"
@@ -176,6 +176,7 @@ int main(int argc, char **argv)
#define DEFAULT_RAM_SIZE 128
#define MAX_VIRTIO_CONSOLES 1
+#define MAX_SCLP_CONSOLES 1
static const char *data_dir;
const char *bios_name = NULL;
@@ -203,6 +204,7 @@ int no_quit = 0;
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
+CharDriverState *sclp_hds[MAX_SCLP_CONSOLES];
int win2k_install_hack = 0;
int singlestep = 0;
int smp_cpus = 1;
@@ -231,7 +233,7 @@ unsigned int nb_prom_envs = 0;
const char *prom_envs[MAX_PROM_ENVS];
int boot_menu;
uint8_t *boot_splash_filedata;
-int boot_splash_filedata_size;
+size_t boot_splash_filedata_size;
uint8_t qemu_extra_params_fw[2];
typedef struct FWBootEntry FWBootEntry;
@@ -261,9 +263,9 @@ static NotifierList exit_notifiers =
static NotifierList machine_init_done_notifiers =
NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
-static int tcg_allowed = 1;
-int kvm_allowed = 0;
-int xen_allowed = 0;
+static bool tcg_allowed = true;
+bool kvm_allowed;
+bool xen_allowed;
uint32_t xen_domid;
enum xen_mode xen_mode = XEN_EMULATE;
static int tcg_tb_size;
@@ -271,6 +273,7 @@ static int tcg_tb_size;
static int default_serial = 1;
static int default_parallel = 1;
static int default_virtcon = 1;
+static int default_sclp = 1;
static int default_monitor = 1;
static int default_floppy = 1;
static int default_cdrom = 1;
@@ -299,6 +302,195 @@ static struct {
{ .driver = "qxl-vga", .flag = &default_vga },
};
+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 = {
+ {
+ .name = "type",
+ .type = QEMU_OPT_STRING,
+ .help = "emulated machine"
+ }, {
+ .name = "accel",
+ .type = QEMU_OPT_STRING,
+ .help = "accelerator list",
+ }, {
+ .name = "kernel_irqchip",
+ .type = QEMU_OPT_BOOL,
+ .help = "use KVM in-kernel irqchip",
+ }, {
+ .name = "kvm_shadow_mem",
+ .type = QEMU_OPT_SIZE,
+ .help = "KVM shadow MMU size",
+ }, {
+ .name = "kernel",
+ .type = QEMU_OPT_STRING,
+ .help = "Linux kernel image file",
+ }, {
+ .name = "initrd",
+ .type = QEMU_OPT_STRING,
+ .help = "Linux initial ramdisk file",
+ }, {
+ .name = "append",
+ .type = QEMU_OPT_STRING,
+ .help = "Linux kernel command line",
+ }, {
+ .name = "dtb",
+ .type = QEMU_OPT_STRING,
+ .help = "Linux kernel device tree file",
+ }, {
+ .name = "dumpdtb",
+ .type = QEMU_OPT_STRING,
+ .help = "Dump current dtb to a file and quit",
+ }, {
+ .name = "phandle_start",
+ .type = QEMU_OPT_STRING,
+ .help = "The first phandle ID we may generate dynamically",
+ }, {
+ .name = "dt_compatible",
+ .type = QEMU_OPT_STRING,
+ .help = "Overrides the \"compatible\" property of the dt root node",
+ }, {
+ .name = "dump-guest-core",
+ .type = QEMU_OPT_BOOL,
+ .help = "Include guest memory in a core dump",
+ }, {
+ .name = "mem-merge",
+ .type = QEMU_OPT_BOOL,
+ .help = "enable/disable memory merge support",
+ },{
+ .name = "usb",
+ .type = QEMU_OPT_BOOL,
+ .help = "Set on/off to enable/disable usb",
+ },
+ { /* End of list */ }
+ },
+};
+
+static QemuOptsList qemu_boot_opts = {
+ .name = "boot-opts",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_boot_opts.head),
+ .desc = {
+ /* the three names below are not used now */
+ {
+ .name = "order",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "once",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "menu",
+ .type = QEMU_OPT_STRING,
+ /* following are really used */
+ }, {
+ .name = "splash",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "splash-time",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "reboot-timeout",
+ .type = QEMU_OPT_STRING,
+ },
+ { /*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 = {
+ { }
+ },
+};
+
const char *qemu_get_vm_name(void)
{
return qemu_name;
@@ -448,21 +640,18 @@ StatusInfo *qmp_query_status(Error **errp)
void qemu_get_timedate(struct tm *tm, int offset)
{
time_t ti;
- struct tm *ret;
time(&ti);
ti += offset;
if (rtc_date_offset == -1) {
if (rtc_utc)
- ret = gmtime(&ti);
+ gmtime_r(&ti, tm);
else
- ret = localtime(&ti);
+ localtime_r(&ti, tm);
} else {
ti -= rtc_date_offset;
- ret = gmtime(&ti);
+ gmtime_r(&ti, tm);
}
-
- memcpy(tm, ret, sizeof(struct tm));
}
int qemu_timedate_diff(struct tm *tm)
@@ -886,9 +1075,9 @@ static int cleanup_add_fd(QemuOpts *opts, void *opaque)
static int drive_init_func(QemuOpts *opts, void *opaque)
{
- int *use_scsi = opaque;
+ BlockInterfaceType *block_default_type = opaque;
- return drive_init(opts, *use_scsi) == NULL;
+ return drive_init(opts, *block_default_type) == NULL;
}
static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
@@ -899,16 +1088,11 @@ static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
return 0;
}
-static void default_drive(int enable, int snapshot, int use_scsi,
- BlockInterfaceType type, int index,
- const char *optstr)
+static void default_drive(int enable, int snapshot, BlockInterfaceType type,
+ int index, const char *optstr)
{
QemuOpts *opts;
- if (type == IF_DEFAULT) {
- type = use_scsi ? IF_SCSI : IF_IDE;
- }
-
if (!enable || drive_get_by_index(type, index)) {
return;
}
@@ -917,7 +1101,7 @@ static void default_drive(int enable, int snapshot, int use_scsi,
if (snapshot) {
drive_enable_snapshot(opts, NULL);
}
- if (!drive_init(opts, use_scsi)) {
+ if (!drive_init(opts, type)) {
exit(1);
}
}
@@ -1017,15 +1201,15 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
* memory pointed by "size" is assigned total length of the array in bytes
*
*/
-char *get_boot_devices_list(uint32_t *size)
+char *get_boot_devices_list(size_t *size)
{
FWBootEntry *i;
- uint32_t total = 0;
+ size_t total = 0;
char *list = NULL;
QTAILQ_FOREACH(i, &fw_boot_order, link) {
char *devpath = NULL, *bootpath;
- int len;
+ size_t len;
if (i->dev) {
devpath = qdev_get_fw_dev_path(i->dev);
@@ -1060,21 +1244,79 @@ char *get_boot_devices_list(uint32_t *size)
return list;
}
-static void numa_add(const char *optarg)
+static void numa_node_parse_cpus(int nodenr, const char *cpus)
{
- char option[128];
char *endptr;
unsigned long long value, endvalue;
- int nodenr;
- value = endvalue = 0ULL;
+ /* Empty CPU range strings will be considered valid, they will simply
+ * not set any bit in the CPU bitmap.
+ */
+ if (!*cpus) {
+ return;
+ }
+
+ if (parse_uint(cpus, &value, &endptr, 10) < 0) {
+ goto error;
+ }
+ if (*endptr == '-') {
+ if (parse_uint_full(endptr + 1, &endvalue, 10) < 0) {
+ goto error;
+ }
+ } else if (*endptr == '\0') {
+ endvalue = value;
+ } else {
+ goto error;
+ }
+
+ if (endvalue >= MAX_CPUMASK_BITS) {
+ endvalue = MAX_CPUMASK_BITS - 1;
+ fprintf(stderr,
+ "qemu: NUMA: A max of %d VCPUs are supported\n",
+ MAX_CPUMASK_BITS);
+ }
+
+ if (endvalue < value) {
+ goto error;
+ }
+
+ bitmap_set(node_cpumask[nodenr], value, endvalue-value+1);
+ return;
- optarg = get_opt_name(option, 128, optarg, ',') + 1;
+error:
+ fprintf(stderr, "qemu: Invalid NUMA CPU range: %s\n", cpus);
+ exit(1);
+}
+
+static void numa_add(const char *optarg)
+{
+ char option[128];
+ char *endptr;
+ unsigned long long nodenr;
+
+ optarg = get_opt_name(option, 128, optarg, ',');
+ if (*optarg == ',') {
+ optarg++;
+ }
if (!strcmp(option, "node")) {
+
+ if (nb_numa_nodes >= MAX_NODES) {
+ fprintf(stderr, "qemu: too many NUMA nodes\n");
+ exit(1);
+ }
+
if (get_param_value(option, 128, "nodeid", optarg) == 0) {
nodenr = nb_numa_nodes;
} else {
- nodenr = strtoull(option, NULL, 10);
+ if (parse_uint_full(option, &nodenr, 10) < 0) {
+ fprintf(stderr, "qemu: Invalid NUMA nodeid: %s\n", option);
+ exit(1);
+ }
+ }
+
+ if (nodenr >= MAX_NODES) {
+ fprintf(stderr, "qemu: invalid NUMA nodeid: %llu\n", nodenr);
+ exit(1);
}
if (get_param_value(option, 128, "mem", optarg) == 0) {
@@ -1089,23 +1331,12 @@ static void numa_add(const char *optarg)
node_mem[nodenr] = sval;
}
if (get_param_value(option, 128, "cpus", optarg) != 0) {
- value = strtoull(option, &endptr, 10);
- if (*endptr == '-') {
- endvalue = strtoull(endptr+1, &endptr, 10);
- } else {
- endvalue = value;
- }
-
- if (!(endvalue < MAX_CPUMASK_BITS)) {
- endvalue = MAX_CPUMASK_BITS - 1;
- fprintf(stderr,
- "A max of %d CPUs are supported in a guest\n",
- MAX_CPUMASK_BITS);
- }
-
- bitmap_set(node_cpumask[nodenr], value, endvalue-value+1);
+ numa_node_parse_cpus(nodenr, option);
}
nb_numa_nodes++;
+ } else {
+ fprintf(stderr, "Invalid -numa option: %s\n", option);
+ exit(1);
}
}
@@ -1268,7 +1499,7 @@ void pcmcia_socket_unregister(PCMCIASocket *socket)
}
}
-void pcmcia_info(Monitor *mon)
+void pcmcia_info(Monitor *mon, const QDict *qdict)
{
struct pcmcia_socket_entry_s *iter;
@@ -2001,7 +2232,7 @@ static int balloon_parse(const char *arg)
return -1;
} else {
/* create empty opts */
- opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0, NULL);
+ opts = qemu_opts_create_nofail(qemu_find_opts("device"));
}
qemu_opt_set(opts, "driver", "virtio-balloon");
return 0;
@@ -2052,16 +2283,20 @@ static int device_init_func(QemuOpts *opts, void *opaque)
dev = qdev_device_add(opts);
if (!dev)
return -1;
+ object_unref(OBJECT(dev));
return 0;
}
static int chardev_init_func(QemuOpts *opts, void *opaque)
{
- CharDriverState *chr;
+ Error *local_err = NULL;
- chr = qemu_chr_new_from_opts(opts, NULL);
- if (!chr)
+ qemu_chr_new_from_opts(opts, NULL, &local_err);
+ if (error_is_set(&local_err)) {
+ fprintf(stderr, "%s\n", error_get_pretty(local_err));
+ error_free(local_err);
return -1;
+ }
return 0;
}
@@ -2156,6 +2391,7 @@ struct device_config {
DEV_VIRTCON, /* -virtioconsole */
DEV_DEBUGCON, /* -debugcon */
DEV_GDB, /* -gdb, -s */
+ DEV_SCLP, /* s390 sclp */
} type;
const char *cmdline;
Location loc;
@@ -2251,14 +2487,14 @@ static int virtcon_parse(const char *devname)
exit(1);
}
- bus_opts = qemu_opts_create(device, NULL, 0, NULL);
+ bus_opts = qemu_opts_create_nofail(device);
if (arch_type == QEMU_ARCH_S390X) {
qemu_opt_set(bus_opts, "driver", "virtio-serial-s390");
} else {
qemu_opt_set(bus_opts, "driver", "virtio-serial-pci");
}
- dev_opts = qemu_opts_create(device, NULL, 0, NULL);
+ dev_opts = qemu_opts_create_nofail(device);
qemu_opt_set(dev_opts, "driver", "virtconsole");
snprintf(label, sizeof(label), "virtcon%d", index);
@@ -2274,6 +2510,39 @@ static int virtcon_parse(const char *devname)
return 0;
}
+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);
+ qemu_opt_set(dev_opts, "driver", "sclpconsole");
+
+ 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;
+ }
+ qemu_opt_set(dev_opts, "chardev", label);
+
+ index++;
+ return 0;
+}
+
static int debugcon_parse(const char *devname)
{
QemuOpts *opts;
@@ -2323,7 +2592,7 @@ static struct {
const char *name;
int (*available)(void);
int (*init)(void);
- int *allowed;
+ bool *allowed;
} accel_list[] = {
{ "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
{ "xen", "Xen", xen_available, xen_init, &xen_allowed },
@@ -2336,8 +2605,8 @@ static int configure_accelerator(void)
const char *p = NULL;
char buf[10];
int i, ret;
- bool accel_initialised = 0;
- bool init_failed = 0;
+ bool accel_initialised = false;
+ bool init_failed = false;
QemuOptsList *list = qemu_find_opts("machine");
if (!QTAILQ_EMPTY(&list->head)) {
@@ -2356,21 +2625,21 @@ static int configure_accelerator(void)
p = get_opt_name(buf, sizeof (buf), p, ':');
for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
if (strcmp(accel_list[i].opt_name, buf) == 0) {
- *(accel_list[i].allowed) = 1;
+ if (!accel_list[i].available()) {
+ printf("%s not supported for this target\n",
+ accel_list[i].name);
+ continue;
+ }
+ *(accel_list[i].allowed) = true;
ret = accel_list[i].init();
if (ret < 0) {
- init_failed = 1;
- if (!accel_list[i].available()) {
- printf("%s not supported for this target\n",
- accel_list[i].name);
- } else {
- fprintf(stderr, "failed to initialize %s: %s\n",
- accel_list[i].name,
- strerror(-ret));
- }
- *(accel_list[i].allowed) = 0;
+ init_failed = true;
+ fprintf(stderr, "failed to initialize %s: %s\n",
+ accel_list[i].name,
+ strerror(-ret));
+ *(accel_list[i].allowed) = false;
} else {
- accel_initialised = 1;
+ accel_initialised = true;
}
break;
}
@@ -2381,7 +2650,9 @@ static int configure_accelerator(void)
}
if (!accel_initialised) {
- fprintf(stderr, "No accelerator found!\n");
+ if (!init_failed) {
+ fprintf(stderr, "No accelerator found!\n");
+ }
exit(1);
}
@@ -2531,7 +2802,7 @@ int main(int argc, char **argv, char **envp)
const char *icount_option = NULL;
const char *initrd_filename;
const char *kernel_filename, *kernel_cmdline;
- char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
+ char boot_devices[33] = "";
DisplayState *ds;
int cyls, heads, secs, translation;
QemuOpts *hda_opts = NULL, *opts, *machine_opts;
@@ -2574,6 +2845,22 @@ int main(int argc, char **argv, char **envp)
module_call_init(MODULE_INIT_QOM);
+ qemu_add_opts(&qemu_drive_opts);
+ 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);
+ 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);
+
runstate_init();
init_clocks();
@@ -2757,10 +3044,6 @@ int main(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_numa:
- if (nb_numa_nodes >= MAX_NODES) {
- fprintf(stderr, "qemu: too many NUMA nodes\n");
- exit(1);
- }
numa_add(optarg);
break;
case QEMU_OPTION_display:
@@ -2852,8 +3135,10 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
}
- qemu_opts_parse(qemu_find_opts("boot-opts"),
- optarg, 0);
+ if (!qemu_opts_parse(qemu_find_opts("boot-opts"),
+ optarg, 0)) {
+ exit(1);
+ }
}
}
break;
@@ -3051,7 +3336,6 @@ int main(int argc, char **argv, char **envp)
}
opts = qemu_opts_parse(olist, optarg, 1);
if (!opts) {
- fprintf(stderr, "parse error: %s\n", optarg);
exit(1);
}
break;
@@ -3067,7 +3351,6 @@ int main(int argc, char **argv, char **envp)
}
opts = qemu_opts_parse(olist, optarg, 1);
if (!opts) {
- fprintf(stderr, "parse error: %s\n", optarg);
exit(1);
}
@@ -3110,8 +3393,7 @@ int main(int argc, char **argv, char **envp)
qemu_opt_set_bool(fsdev, "readonly",
qemu_opt_get_bool(opts, "readonly", 0));
- device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
- NULL);
+ device = qemu_opts_create_nofail(qemu_find_opts("device"));
qemu_opt_set(device, "driver", "virtio-9p-pci");
qemu_opt_set(device, "fsdev",
qemu_opt_get(opts, "mount_tag"));
@@ -3131,8 +3413,7 @@ int main(int argc, char **argv, char **envp)
}
qemu_opt_set(fsdev, "fsdriver", "synth");
- device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
- NULL);
+ device = qemu_opts_create_nofail(qemu_find_opts("device"));
qemu_opt_set(device, "driver", "virtio-9p-pci");
qemu_opt_set(device, "fsdev", "v_synth");
qemu_opt_set(device, "mount_tag", "v_synth");
@@ -3240,7 +3521,6 @@ int main(int argc, char **argv, char **envp)
olist = qemu_find_opts("machine");
opts = qemu_opts_parse(olist, optarg, 1);
if (!opts) {
- fprintf(stderr, "parse error: %s\n", optarg);
exit(1);
}
optarg = qemu_opt_get(opts, "type");
@@ -3345,6 +3625,9 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
opts = qemu_opts_parse(qemu_find_opts("option-rom"), optarg, 1);
+ if (!opts) {
+ exit(1);
+ }
option_rom[nb_option_roms].name = qemu_opt_get(opts, "romfile");
option_rom[nb_option_roms].bootindex =
qemu_opt_get_number(opts, "bootindex", -1);
@@ -3417,6 +3700,7 @@ int main(int argc, char **argv, char **envp)
default_serial = 0;
default_parallel = 0;
default_virtcon = 0;
+ default_sclp = 0;
default_monitor = 0;
default_net = 0;
default_floppy = 0;
@@ -3473,7 +3757,6 @@ int main(int argc, char **argv, char **envp)
}
opts = qemu_opts_parse(olist, optarg, 0);
if (!opts) {
- fprintf(stderr, "parse error: %s\n", optarg);
exit(1);
}
break;
@@ -3502,14 +3785,14 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_sandbox:
opts = qemu_opts_parse(qemu_find_opts("sandbox"), optarg, 1);
if (!opts) {
- exit(0);
+ exit(1);
}
break;
case QEMU_OPTION_add_fd:
#ifndef _WIN32
opts = qemu_opts_parse(qemu_find_opts("add-fd"), optarg, 0);
if (!opts) {
- exit(0);
+ exit(1);
}
#else
error_report("File descriptor passing is disabled on this "
@@ -3519,6 +3802,9 @@ int main(int argc, char **argv, char **envp)
break;
case QEMU_OPTION_object:
opts = qemu_opts_parse(qemu_find_opts("object"), optarg, 1);
+ if (!opts) {
+ exit(1);
+ }
break;
default:
os_parse_cmd_args(popt->index, optarg);
@@ -3634,6 +3920,9 @@ int main(int argc, char **argv, char **envp)
if (!machine->use_virtcon) {
default_virtcon = 0;
}
+ if (!machine->use_sclp) {
+ default_sclp = 0;
+ }
if (machine->no_floppy) {
default_floppy = 0;
}
@@ -3644,6 +3933,30 @@ int main(int argc, char **argv, char **envp)
default_sdcard = 0;
}
+ 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
+ }
+
if (display_type == DT_NOGRAPHIC) {
if (default_parallel)
add_device_config(DEV_PARALLEL, "null");
@@ -3651,11 +3964,16 @@ int main(int argc, char **argv, char **envp)
add_device_config(DEV_SERIAL, "mon:stdio");
} else if (default_virtcon && default_monitor) {
add_device_config(DEV_VIRTCON, "mon:stdio");
+ } else if (default_sclp && default_monitor) {
+ add_device_config(DEV_SCLP, "mon:stdio");
} else {
if (default_serial)
add_device_config(DEV_SERIAL, "stdio");
if (default_virtcon)
add_device_config(DEV_VIRTCON, "stdio");
+ if (default_sclp) {
+ add_device_config(DEV_SCLP, "stdio");
+ }
if (default_monitor)
monitor_parse("stdio", "readline");
}
@@ -3668,6 +3986,9 @@ int main(int argc, char **argv, char **envp)
monitor_parse("vc:80Cx24C", "readline");
if (default_virtcon)
add_device_config(DEV_VIRTCON, "vc:80Cx24C");
+ if (default_sclp) {
+ add_device_config(DEV_SCLP, "vc:80Cx24C");
+ }
}
socket_init();
@@ -3745,6 +4066,9 @@ int main(int argc, char **argv, char **envp)
}
configure_icount(icount_option);
+ /* clean up network at qemu process termination */
+ atexit(&net_cleanup);
+
if (net_init_clients() < 0) {
exit(1);
}
@@ -3770,15 +4094,15 @@ int main(int argc, char **argv, char **envp)
/* open the virtual block devices */
if (snapshot)
qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0);
- if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, &machine->use_scsi, 1) != 0)
+ if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func,
+ &machine->block_default_type, 1) != 0) {
exit(1);
+ }
- default_drive(default_cdrom, snapshot, machine->use_scsi,
- IF_DEFAULT, 2, CDROM_OPTS);
- default_drive(default_floppy, snapshot, machine->use_scsi,
- IF_FLOPPY, 0, FD_OPTS);
- default_drive(default_sdcard, snapshot, machine->use_scsi,
- IF_SD, 0, SD_OPTS);
+ default_drive(default_cdrom, snapshot, machine->block_default_type, 2,
+ CDROM_OPTS);
+ default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS);
+ default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS);
register_savevm_live(NULL, "ram", 0, 4, &savevm_ram_handlers, NULL);
@@ -3835,6 +4159,9 @@ int main(int argc, char **argv, char **envp)
exit(1);
if (foreach_device_config(DEV_VIRTCON, virtcon_parse) < 0)
exit(1);
+ if (foreach_device_config(DEV_SCLP, sclp_parse) < 0) {
+ exit(1);
+ }
if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
exit(1);
@@ -3862,7 +4189,9 @@ int main(int argc, char **argv, char **envp)
qdev_machine_init();
QEMUMachineInitArgs args = { .ram_size = ram_size,
- .boot_device = boot_devices,
+ .boot_device = (boot_devices[0] == '\0') ?
+ machine->boot_order :
+ boot_devices,
.kernel_filename = kernel_filename,
.kernel_cmdline = kernel_cmdline,
.initrd_filename = initrd_filename,
@@ -3910,9 +4239,7 @@ int main(int argc, char **argv, char **envp)
break;
#if defined(CONFIG_CURSES)
case DT_CURSES:
- if (!is_daemonized()) {
- curses_display_init(ds, full_screen);
- }
+ curses_display_init(ds, full_screen);
break;
#endif
#if defined(CONFIG_SDL)
@@ -3999,7 +4326,6 @@ int main(int argc, char **argv, char **envp)
main_loop();
bdrv_close_all();
pause_all_vcpus();
- net_cleanup();
res_free();
return 0;