diff options
author | Linaro Packagers <linaro-pkg@lists.launchpad.net> | 2013-02-25 10:33:42 +0000 |
---|---|---|
committer | Fathi Boudra <fathi.boudra@linaro.org> | 2013-03-30 21:18:26 +0200 |
commit | c3565b8703553405641c76a4c40961473d051edd (patch) | |
tree | 01be1a3169d8c72f8e0fd406b81eea561e7f87e7 /vl.c | |
parent | edde41b3c75bce779549bd2e1dba18eb7beb8267 (diff) | |
parent | 050a840ead5e51a1a9f3bffe89cc89077b2f35ed (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.c | 572 |
1 files changed, 449 insertions, 123 deletions
@@ -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; |