Since we have MachineCore and can represent a machine entirely via default options, we can introduce a new option that let's us dynamically register a machine based on those options.
For instance, we could add the following to target-x86_64.conf: [machine-def] name = "pc-0.11" desc = "Standard PC" acpi = "on" pci = "on" cpu = "qemu64" max_cpus = "255" virtio-blk-pci.vectors = "0" virtio-serial-pci.max_nr_ports = "1" virtio-serial-pci.vectors = "0" ide-drive.ver = "0.11" scsi-disk.ver = "0.11" PCI.rombar = "0" What's really exciting, is that a user can then define their own machines that better suite their desires: [kvmpc] name = "kvmpc" accel = "kvm|tcg" ram_size = "512M" max_cpus = "64" sockets = "16" default_drive = "virtio" I'd eventually like to move all PC compatibility machines to the default config but for now, I wanted to keep this simple. Signed-off-by: Anthony Liguori <aligu...@us.ibm.com> diff --git a/qemu-config.c b/qemu-config.c index a0cb34f..9b5415d 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -345,6 +345,15 @@ QemuOptsList qemu_machine_opts = { }, }; +QemuOptsList qemu_machine_def_opts = { + .name = "machine-def", + .implied_opt_name = "name", + .head = QTAILQ_HEAD_INITIALIZER(qemu_machine_def_opts.head), + .desc = { + { /* end of list */ } + }, +}; + static QemuOptsList *vm_config_groups[] = { &qemu_drive_opts, &qemu_chardev_opts, @@ -356,6 +365,7 @@ static QemuOptsList *vm_config_groups[] = { &qemu_mon_opts, &qemu_cpudef_opts, &qemu_machine_opts, + &qemu_machine_def_opts, NULL, }; diff --git a/qemu-config.h b/qemu-config.h index 6f52188..1b7324c 100644 --- a/qemu-config.h +++ b/qemu-config.h @@ -15,6 +15,7 @@ extern QemuOptsList qemu_global_opts; extern QemuOptsList qemu_mon_opts; extern QemuOptsList qemu_cpudef_opts; extern QemuOptsList qemu_machine_opts; +extern QemuOptsList qemu_machine_def_opts; QemuOptsList *qemu_find_opts(const char *group); int qemu_set_option(const char *str); diff --git a/qemu-options.hx b/qemu-options.hx index 32fd32a..2bafe22 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -43,6 +43,14 @@ STEXI Select the emulated @var{machine} ETEXI +DEF("machine-def", HAS_ARG, QEMU_OPTION_machine_def, + "-machine-def name[,opt=val...] define a new machine\n", QEMU_ARCH_ALL) +STEXI +...@item -machine-def @var{name}[,@var{op...@var{val}...] +...@findex -machine-def +Define a new machine +ETEXI + DEF("cpu", HAS_ARG, QEMU_OPTION_cpu, "-cpu cpu select CPU (-cpu ? for list)\n", QEMU_ARCH_ALL) STEXI diff --git a/vl.c b/vl.c index 150dd41..7797187 100644 --- a/vl.c +++ b/vl.c @@ -1683,6 +1683,59 @@ void machine_set_default(const char *name) default_machine = name; } +typedef struct MachineDefineHelper +{ + QemuOptValue *defaults; + int length; + int capacity; +} MachineDefineHelper; + +static void helper_grow(MachineDefineHelper *helper) +{ + if ((helper->capacity - helper->length) < 2) { + helper->capacity += 100; + helper->defaults = qemu_realloc(helper->defaults, + helper->capacity * sizeof(QemuOptValue)); + } +} + +static int machine_define_prop(const char *name, const char *value, void *opaque) +{ + MachineDefineHelper *helper = opaque; + QemuOptValue *v; + + if (strcmp(name, "core") == 0) { + return 0; + } + + helper_grow(helper); + v = &helper->defaults[helper->length++]; + v->name = qemu_strdup(name); + v->value = qemu_strdup(value); + + return 0; +} + +static int machine_define(QemuOpts *opts, void *opaque) +{ + MachineDefineHelper *helper; + const char *core; + + core = qemu_opt_get(opts, "core"); + if (!core) { + fprintf(stderr, "machine-def: No core specified\n"); + return -1; + } + + helper = qemu_mallocz(sizeof(*helper)); + qemu_opt_foreach(opts, machine_define_prop, helper, 1); + helper->defaults[helper->length].name = NULL; + machine_create_from_core(core, helper->defaults); + qemu_free(helper); + + return 0; +} + static Machine *find_machine(const char *name) { Machine *m; @@ -2812,6 +2865,7 @@ int main(int argc, char **argv, char **envp) } } cpudef_init(); + qemu_opts_foreach(&qemu_machine_def_opts, machine_define, NULL, 1); /* second pass of option parsing */ optind = 1; @@ -2853,6 +2907,14 @@ int main(int argc, char **argv, char **envp) exit(1); } break; + case QEMU_OPTION_machine_def: + opts = qemu_opts_parse(&qemu_machine_def_opts, optarg, 1); + if (!opts) { + exit(1); + } + + machine_define(opts, NULL); + break; case QEMU_OPTION_cpu: /* hw initialization will check this */ if (*optarg == '?') { -- 1.7.0.4