diff options
Diffstat (limited to 'vl.c')
-rw-r--r-- | vl.c | 202 |
1 files changed, 153 insertions, 49 deletions
@@ -120,8 +120,6 @@ int main(int argc, char **argv) #include "qom/object_interfaces.h" #include "qapi-event.h" -#define DEFAULT_RAM_SIZE 128 - #define MAX_VIRTIO_CONSOLES 1 #define MAX_SCLP_CONSOLES 1 @@ -233,6 +231,7 @@ static struct { { .driver = "isa-cirrus-vga", .flag = &default_vga }, { .driver = "vmware-svga", .flag = &default_vga }, { .driver = "qxl-vga", .flag = &default_vga }, + { .driver = "virtio-vga", .flag = &default_vga }, }; static QemuOptsList qemu_rtc_opts = { @@ -470,6 +469,9 @@ static QemuOptsList qemu_icount_opts = { }, { .name = "align", .type = QEMU_OPT_BOOL, + }, { + .name = "sleep", + .type = QEMU_OPT_BOOL, }, { /* end of list */ } }, @@ -491,6 +493,25 @@ static QemuOptsList qemu_semihosting_config_opts = { }, }; +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 */ } + }, +}; + /** * Get machine options * @@ -514,7 +535,7 @@ static void res_free(void) } } -static int default_driver_check(QemuOpts *opts, void *opaque) +static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp) { const char *driver = qemu_opt_get(opts, "driver"); int i; @@ -960,7 +981,7 @@ static int bt_parse(const char *opt) return 1; } -static int parse_sandbox(QemuOpts *opts, void *opaque) +static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) { /* FIXME: change this to true for 1.3 */ if (qemu_opt_get_bool(opts, "enable", false)) { @@ -980,7 +1001,7 @@ static int parse_sandbox(QemuOpts *opts, void *opaque) return 0; } -static int parse_name(QemuOpts *opts, void *opaque) +static int parse_name(void *opaque, QemuOpts *opts, Error **errp) { const char *proc_name; @@ -1008,7 +1029,7 @@ bool usb_enabled(void) } #ifndef _WIN32 -static int parse_add_fd(QemuOpts *opts, void *opaque) +static int parse_add_fd(void *opaque, QemuOpts *opts, Error **errp) { int fd, dupfd, flags; int64_t fdset_id; @@ -1070,7 +1091,7 @@ static int parse_add_fd(QemuOpts *opts, void *opaque) return 0; } -static int cleanup_add_fd(QemuOpts *opts, void *opaque) +static int cleanup_add_fd(void *opaque, QemuOpts *opts, Error **errp) { int fd; @@ -1091,14 +1112,14 @@ static int cleanup_add_fd(QemuOpts *opts, void *opaque) #define MTD_OPTS "" #define SD_OPTS "" -static int drive_init_func(QemuOpts *opts, void *opaque) +static int drive_init_func(void *opaque, QemuOpts *opts, Error **errp) { BlockInterfaceType *block_default_type = opaque; return drive_new(opts, *block_default_type) == NULL; } -static int drive_enable_snapshot(QemuOpts *opts, void *opaque) +static int drive_enable_snapshot(void *opaque, QemuOpts *opts, Error **errp) { if (qemu_opt_get(opts, "snapshot") == NULL) { qemu_opt_set(opts, "snapshot", "on", &error_abort); @@ -1118,7 +1139,7 @@ static void default_drive(int enable, int snapshot, BlockInterfaceType type, opts = drive_add(type, index, NULL, optstr); if (snapshot) { - drive_enable_snapshot(opts, NULL); + drive_enable_snapshot(NULL, opts, NULL); } dinfo = drive_new(opts, type); @@ -1310,7 +1331,11 @@ void hmp_usb_del(Monitor *mon, const QDict *qdict) MachineState *current_machine; -static void machine_class_init(ObjectClass *oc, void *data) +/* + * Transitional class registration/init used for converting from + * legacy QEMUMachine to MachineClass. + */ +static void qemu_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); QEMUMachine *qm = data; @@ -1333,7 +1358,7 @@ int qemu_register_machine(QEMUMachine *m) TypeInfo ti = { .name = name, .parent = TYPE_MACHINE, - .class_init = machine_class_init, + .class_init = qemu_machine_class_init, .class_data = (void *)m, }; @@ -1860,6 +1885,11 @@ static bool cg3_vga_available(void) return object_class_by_name("cgthree"); } +static bool virtio_vga_available(void) +{ + return object_class_by_name("virtio-vga"); +} + static void select_vgahw (const char *p) { const char *opts; @@ -1886,6 +1916,13 @@ static void select_vgahw (const char *p) fprintf(stderr, "Error: VMWare SVGA not available\n"); exit(0); } + } 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); + } } else if (strstart(p, "xenfb", &opts)) { vga_interface_type = VGA_XENFB; } else if (strstart(p, "qxl", &opts)) { @@ -2122,12 +2159,44 @@ char *qemu_find_file(int type, const char *name) return NULL; } -static int device_help_func(QemuOpts *opts, void *opaque) +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; +} + +static int device_help_func(void *opaque, QemuOpts *opts, Error **errp) { return qdev_device_help(opts); } -static int device_init_func(QemuOpts *opts, void *opaque) +static int device_init_func(void *opaque, QemuOpts *opts, Error **errp) { DeviceState *dev; @@ -2138,7 +2207,7 @@ static int device_init_func(QemuOpts *opts, void *opaque) return 0; } -static int chardev_init_func(QemuOpts *opts, void *opaque) +static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp) { Error *local_err = NULL; @@ -2151,7 +2220,7 @@ static int chardev_init_func(QemuOpts *opts, void *opaque) } #ifdef CONFIG_VIRTFS -static int fsdev_init_func(QemuOpts *opts, void *opaque) +static int fsdev_init_func(void *opaque, QemuOpts *opts, Error **errp) { int ret; ret = qemu_fsdev_add(opts); @@ -2160,7 +2229,7 @@ static int fsdev_init_func(QemuOpts *opts, void *opaque) } #endif -static int mon_init_func(QemuOpts *opts, void *opaque) +static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp) { CharDriverState *chr; const char *chardev; @@ -2495,14 +2564,20 @@ static void qemu_run_exit_notifiers(void) notifier_list_notify(&exit_notifiers, NULL); } +static bool machine_init_done; + void qemu_add_machine_init_done_notifier(Notifier *notify) { notifier_list_add(&machine_init_done_notifiers, notify); + if (machine_init_done) { + notify->notify(notify, NULL); + } } static void qemu_run_machine_init_done_notifiers(void) { notifier_list_notify(&machine_init_done_notifiers, NULL); + machine_init_done = true; } static const QEMUOption *lookup_opt(int argc, char **argv, @@ -2565,8 +2640,9 @@ static void free_and_trace(gpointer mem) free(mem); } -static int machine_set_property(const char *name, const char *value, - void *opaque) +static int machine_set_property(void *opaque, + const char *name, const char *value, + Error **errp) { Object *obj = OBJECT(opaque); Error *local_err = NULL; @@ -2595,7 +2671,7 @@ static int machine_set_property(const char *name, const char *value, return 0; } -static int object_create(QemuOpts *opts, void *opaque) +static int object_create(void *opaque, QemuOpts *opts, Error **errp) { Error *err = NULL; char *type = NULL; @@ -2647,13 +2723,13 @@ out: return 0; } -static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size) +static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size, + MachineClass *mc) { uint64_t sz; const char *mem_str; const char *maxmem_str, *slots_str; - const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE * - 1024 * 1024; + const ram_addr_t default_ram_size = mc->default_ram_size; QemuOpts *opts = qemu_find_opts_singleton("memory"); sz = 0; @@ -2810,6 +2886,7 @@ int main(int argc, char **argv, char **envp) qemu_add_opts(&qemu_numa_opts); qemu_add_opts(&qemu_icount_opts); qemu_add_opts(&qemu_semihosting_config_opts); + qemu_add_opts(&qemu_fw_cfg_opts); runstate_init(); @@ -3426,6 +3503,12 @@ int main(int argc, char **argv, char **envp) } do_smbios_option(opts); break; + case QEMU_OPTION_fwcfg: + opts = qemu_opts_parse(qemu_find_opts("fw_cfg"), optarg, 1); + if (opts == NULL) { + exit(1); + } + break; case QEMU_OPTION_enable_kvm: olist = qemu_find_opts("machine"); qemu_opts_parse(olist, "accel=kvm", 0); @@ -3769,7 +3852,13 @@ int main(int argc, char **argv, char **envp) machine_class = machine_parse(optarg); } - set_memory_options(&ram_slots, &maxram_size); + 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); loc_set_none(); @@ -3780,30 +3869,28 @@ int main(int argc, char **argv, char **envp) exit(1); } - if (qemu_opts_foreach(qemu_find_opts("sandbox"), parse_sandbox, NULL, 0)) { + if (qemu_opts_foreach(qemu_find_opts("sandbox"), + parse_sandbox, NULL, NULL)) { exit(1); } - if (qemu_opts_foreach(qemu_find_opts("name"), parse_name, NULL, 1)) { + if (qemu_opts_foreach(qemu_find_opts("name"), + parse_name, NULL, NULL)) { exit(1); } #ifndef _WIN32 - if (qemu_opts_foreach(qemu_find_opts("add-fd"), parse_add_fd, NULL, 1)) { + if (qemu_opts_foreach(qemu_find_opts("add-fd"), + parse_add_fd, NULL, NULL)) { exit(1); } - if (qemu_opts_foreach(qemu_find_opts("add-fd"), cleanup_add_fd, NULL, 1)) { + if (qemu_opts_foreach(qemu_find_opts("add-fd"), + cleanup_add_fd, NULL, NULL)) { exit(1); } #endif - 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); - } - current_machine = MACHINE(object_new(object_class_get_name( OBJECT_CLASS(machine_class)))); if (machine_help_func(qemu_get_machine_opts(), current_machine)) { @@ -3886,8 +3973,10 @@ int main(int argc, char **argv, char **envp) machine_class->default_machine_opts, 0); } - qemu_opts_foreach(qemu_find_opts("device"), default_driver_check, NULL, 0); - qemu_opts_foreach(qemu_find_opts("global"), default_driver_check, NULL, 0); + qemu_opts_foreach(qemu_find_opts("device"), + default_driver_check, NULL, NULL); + qemu_opts_foreach(qemu_find_opts("global"), + default_driver_check, NULL, NULL); if (!vga_model && !default_vga) { vga_interface_type = VGA_DEVICE; @@ -4025,10 +4114,14 @@ int main(int argc, char **argv, char **envp) socket_init(); - if (qemu_opts_foreach(qemu_find_opts("chardev"), chardev_init_func, NULL, 1) != 0) + if (qemu_opts_foreach(qemu_find_opts("chardev"), + chardev_init_func, NULL, NULL)) { exit(1); + } + #ifdef CONFIG_VIRTFS - if (qemu_opts_foreach(qemu_find_opts("fsdev"), fsdev_init_func, NULL, 1) != 0) { + if (qemu_opts_foreach(qemu_find_opts("fsdev"), + fsdev_init_func, NULL, NULL)) { exit(1); } #endif @@ -4038,19 +4131,19 @@ int main(int argc, char **argv, char **envp) exit(1); } - if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0) - != 0) { + if (qemu_opts_foreach(qemu_find_opts("device"), + device_help_func, NULL, NULL)) { exit(0); } if (qemu_opts_foreach(qemu_find_opts("object"), - object_create, NULL, 0) != 0) { + object_create, NULL, NULL)) { exit(1); } machine_opts = qemu_get_machine_opts(); if (qemu_opt_foreach(machine_opts, machine_set_property, current_machine, - 1) < 0) { + NULL)) { object_unref(OBJECT(current_machine)); exit(1); } @@ -4178,9 +4271,10 @@ 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); + qemu_opts_foreach(qemu_find_opts("drive"), + drive_enable_snapshot, NULL, NULL); if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, - &machine_class->block_default_type, 1) != 0) { + &machine_class->block_default_type, NULL)) { exit(1); } @@ -4191,7 +4285,8 @@ int main(int argc, char **argv, char **envp) parse_numa_opts(machine_class); - if (qemu_opts_foreach(qemu_find_opts("mon"), mon_init_func, NULL, 1) != 0) { + if (qemu_opts_foreach(qemu_find_opts("mon"), + mon_init_func, NULL, NULL)) { exit(1); } @@ -4250,6 +4345,11 @@ int main(int argc, char **argv, char **envp) numa_post_machine_init(); + if (qemu_opts_foreach(qemu_find_opts("fw_cfg"), + parse_fw_cfg, fw_cfg_find(), NULL) != 0) { + exit(1); + } + /* init USB devices */ if (usb_enabled()) { if (foreach_device_config(DEV_USB, usb_parse) < 0) @@ -4257,8 +4357,10 @@ int main(int argc, char **argv, char **envp) } /* init generic devices */ - if (qemu_opts_foreach(qemu_find_opts("device"), device_init_func, NULL, 1) != 0) + if (qemu_opts_foreach(qemu_find_opts("device"), + device_init_func, NULL, NULL)) { exit(1); + } /* Did we create any drives that we failed to create a device for? */ drive_check_orphaned(); @@ -4310,10 +4412,12 @@ int main(int argc, char **argv, char **envp) #ifdef CONFIG_VNC /* init remote displays */ - qemu_opts_foreach(qemu_find_opts("vnc"), vnc_init_func, NULL, 0); + qemu_opts_foreach(qemu_find_opts("vnc"), + vnc_init_func, NULL, NULL); if (show_vnc_port) { - printf("VNC server running on `%s'\n", - vnc_display_local_addr("default")); + char *ret = vnc_display_local_addr("default"); + printf("VNC server running on `%s'\n", ret); + g_free(ret); } #endif #ifdef CONFIG_SPICE |