From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=37280 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OLn1J-0003LP-1X for qemu-devel@nongnu.org; Mon, 07 Jun 2010 20:50:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OLn1G-0001Y7-Rd for qemu-devel@nongnu.org; Mon, 07 Jun 2010 20:50:20 -0400 Received: from mail-yw0-f197.google.com ([209.85.211.197]:49643) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OLn1G-0001Xx-IS for qemu-devel@nongnu.org; Mon, 07 Jun 2010 20:50:18 -0400 Received: by ywh35 with SMTP id 35so3787972ywh.29 for ; Mon, 07 Jun 2010 17:50:17 -0700 (PDT) Message-ID: <4C0D93C6.1020805@codemonkey.ws> Date: Mon, 07 Jun 2010 19:50:14 -0500 From: Anthony Liguori MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH 22/22] machine: introduce -machine-def option to define a machine via config References: <1275954730-8196-1-git-send-email-aliguori@us.ibm.com> <1275954730-8196-23-git-send-email-aliguori@us.ibm.com> In-Reply-To: <1275954730-8196-23-git-send-email-aliguori@us.ibm.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori Cc: Glauber Costa , qemu-devel@nongnu.org On 06/07/2010 06:52 PM, Anthony Liguori wrote: > 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 > From the perspective of a tool like libvirt, I think there are a couple ways it could handle something like this and I think it's worth discussing the options. Assume we move all the compat machine definitions into a config file, since libvirt presumably uses -nodefconfig today, it could simply include it's own machine definitions for each qemu version based on the definitions we ship. That makes sure that the definition is always static for libvirt. Another option would be for libvirt to not use -nodefconfig, and instead to let the user's global configs be read. libvirt would then read the config file from the running qemu instance to sync it's state up. The later option is a bit more work up front but longer term, I think it addresses a couple things nicely. It provides a way for a user specified config to co-exist with libvirt. It also let's tools tweak power config options in a way that's compatible with libvirt. If libvirt can embed the qemu config description in its own XML, then there is no problem for libvirt to recreate the system on a different box even if the global configuration is different. Regards, Anthony Liguori > 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{opt}=@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 == '?') { >