[Qemu-devel] [PATCH v2 2/4] qdev-monitor: Implement three functions used to connect devices

2014-04-10 Thread Alistair Francis
These functions are used to attach devices that are passed in
via the command line using the -device argument.

The reason for using three functions is to allow a multi-pass
approach. This can then be extended to allow devices to
connect to other devices that are being connected via the
command line (for example DMA/ethernet AXI-Stream).

Signed-off-by: Alistair Francis 
---

 include/hw/boards.h   |2 +
 include/monitor/qdev.h|3 +
 include/qemu/option_int.h |1 +
 qdev-monitor.c|  237 -
 4 files changed, 241 insertions(+), 2 deletions(-)

diff --git a/include/hw/boards.h b/include/hw/boards.h
index dd2c70d..d06bf86 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -15,6 +15,8 @@ typedef struct QEMUMachineInitArgs {
 const char *kernel_cmdline;
 const char *initrd_filename;
 const char *cpu_model;
+DeviceState *intc;
+Object *cpu;
 } QEMUMachineInitArgs;
 
 typedef void QEMUMachineInitFunc(QEMUMachineInitArgs *args);
diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h
index 8d16e11..18a5b3d 100644
--- a/include/monitor/qdev.h
+++ b/include/monitor/qdev.h
@@ -11,5 +11,8 @@ void do_info_qdm(Monitor *mon, const QDict *qdict);
 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
 int qdev_device_help(QemuOpts *opts);
 DeviceState *qdev_device_add(QemuOpts *opts);
+DeviceState *qdev_device_create(QemuOpts *opts);
+DeviceState *qdev_device_init(QemuOpts *opts, DeviceState* intc);
+DeviceState *qdev_device_connect(QemuOpts *opts, DeviceState* intc);
 
 #endif
diff --git a/include/qemu/option_int.h b/include/qemu/option_int.h
index 8212fa4..fdab055 100644
--- a/include/qemu/option_int.h
+++ b/include/qemu/option_int.h
@@ -47,6 +47,7 @@ struct QemuOpts {
 char *id;
 QemuOptsList *list;
 Location loc;
+void *opaque;
 QTAILQ_HEAD(QemuOptHead, QemuOpt) head;
 QTAILQ_ENTRY(QemuOpts) next;
 };
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 9268c87..5920cb6 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -24,6 +24,8 @@
 #include "qmp-commands.h"
 #include "sysemu/arch_init.h"
 #include "qemu/config-file.h"
+#include "exec/address-spaces.h"
+#include "qemu/option_int.h"
 
 /*
  * Aliases were a bad idea from the start.  Let's keep them
@@ -148,10 +150,27 @@ static int set_property(const char *name, const char 
*value, void *opaque)
 Object *obj = opaque;
 Error *err = NULL;
 
-if (strcmp(name, "driver") == 0)
+if (strcmp(name, "driver") == 0) {
 return 0;
-if (strcmp(name, "bus") == 0)
+}
+if (strcmp(name, "bus") == 0) {
+return 0;
+}
+if (strcmp(name, "addr") == 0) {
+return 0;
+}
+if (strcmp(name, "irq") == 0) {
+return 0;
+}
+if (strcmp(name, "model") == 0) {
+return 0;
+}
+if (strcmp(name, "name") == 0) {
 return 0;
+}
+if (strcmp(name, "type") == 0) {
+return 0;
+}
 
 object_property_parse(obj, value, name, &err);
 if (err != NULL) {
@@ -567,6 +586,220 @@ DeviceState *qdev_device_add(QemuOpts *opts)
 }
 
 
+DeviceState *qdev_device_create(QemuOpts *opts)
+{
+ObjectClass *oc;
+DeviceClass *dc;
+const char *driver, *path;
+DeviceState *dev = NULL;
+BusState *bus = NULL;
+
+hwaddr addr;
+MemoryRegion *ram;
+MemoryRegion *address_space_mem = get_system_memory();;
+uint64_t ram_size;
+
+Object *cpu;
+ObjectClass *cpu_oc;
+Error *err = NULL;
+
+driver = qemu_opt_get(opts, "driver");
+if (!driver) {
+qerror_report(QERR_MISSING_PARAMETER, "driver");
+exit(1);
+}
+
+if (!strcmp(driver, "cpu")) {
+/* The device being added is a cpu */
+if (qemu_opt_get(opts, "name")) {
+cpu = object_new(qemu_opt_get(opts, "name"));
+} else {
+cpu_oc = cpu_class_by_name(qemu_opt_get(opts, "type"),
+   qemu_opt_get(opts, "model"));
+cpu = object_new(object_class_get_name(cpu_oc));
+}
+
+/* Set Properties */
+qemu_opt_foreach(opts, set_property, cpu, 1);
+
+object_property_set_bool(cpu, true, "realized", &err);
+if (err) {
+error_report("%s", error_get_pretty(err));
+exit(1);
+}
+
+return NULL;
+}
+
+if (!strcmp(driver, "memory")) {
+/* The device being added is a memory controller */
+ram = g_new(MemoryRegion, 1);
+
+sscanf(qemu_opt_get(opts, "size"), "%X", (uint *) &ram_size);
+sscanf(qemu_opt_get(opts, "addr"), "%X", (uint *) &addr);
+
+memory_region_init_ram(ram, NULL, qemu_opt_get(opts, "name"),
+   (uint) ram_size);
+vmstate_register_ram_global(ram);
+memory_region_add_subregion(address_space_mem, (uint) addr, ram);
+
+return NULL;
+}
+
+/* find the driver */
+oc = object_class_by_

Re: [Qemu-devel] [PATCH v2 0/4] Allow sysbus devices to be attached via commandline

2014-04-10 Thread Alistair Francis
CC Konstanty

On Fri, Apr 11, 2014 at 4:34 PM, Alistair Francis
 wrote:
> This patch allows sysbus devices to be attached via
> command line arguments.
>
> This can be used to build an entire machine from the command
> line or to just add devices that aren't in the machine_init
> code.
>
> A peripheral can be added with the following syntax:
> -device cadence_uart,addr=0xE000,irq=27
>
> A CPU can be added with either of the following:
> -device cpu,model=cortex-a9,type=arm-cpu,reset-cbar=0xF8F0,midr=0x413 
>FC090
> -sysbusdev device=cpu,name=microblaze-cp
>
> RAM or ROM can be attached with this command:
> -device memory,name=zynq.ext_ram,addr=0x,size=0x800
>
> Multiple IRQ lines can be used as well as multiple properties:
> -device pl330,addr=0xF8003000,irq=13,irq=14,irq=15,irq=16,irq=17,\
> irq=40,irq=41,irq=42,irq=43,num_chnls=8,num_periph_req=4,num_events=16
>
> This implementation uses a three round multi-pass method. This will
> hopefully allow devices attached via the command line to be connected
> to other command line devices (I haven't managed to get that working
> yet though)
>
> With Li Guang's blob loader implemented it is also possible to boot
> images while using "-M none".
>
> V2:
> Use -device to attach the devices (Thanks Markus Armbruster)
> Make the method much more generic
> Allow CPUs and Memory to be attached via command line
> Allow properties to be passed in via the command line
>
> Thanks to Markus Armbruster and Peter Crosthwaite for
> feedback on the first version
>
>
> Alistair Francis (4):
>   qemu-option.c: Add qemu_opt functions that step over arguments
>   qdev-monitor: Implement three functions used to connect devices
>   vl.c: Enable adding devices to the system bus
>   qemu-options.hx: Update the command line documentation for -device
>
>  include/hw/boards.h   |2 +
>  include/monitor/qdev.h|3 +
>  include/qemu/option.h |2 +
>  include/qemu/option_int.h |1 +
>  qdev-monitor.c|  237 
> -
>  qemu-options.hx   |8 +-
>  util/qemu-option.c|   30 ++
>  vl.c  |   74 +-
>  8 files changed, 346 insertions(+), 11 deletions(-)
>



[Qemu-devel] [PATCH v2 3/4] vl.c: Enable adding devices to the system bus

2014-04-10 Thread Alistair Francis
This removes the old method to connect devices and replaces it
with three calls to the three qdev-monitor functions added
in the previous patch.

This allows complete machines to be built via the command line as
well as just attaching simple sysbus devices.

Signed-off-by: Alistair Francis 
---

 vl.c |   74 -
 1 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/vl.c b/vl.c
index 9975e5a..809882c 100644
--- a/vl.c
+++ b/vl.c
@@ -97,6 +97,7 @@ int main(int argc, char **argv)
 #include "qemu-options.h"
 #include "qmp-commands.h"
 #include "qemu/main-loop.h"
+#include "qemu/option_int.h"
 #ifdef CONFIG_VIRTFS
 #include "fsdev/qemu-fsdev.h"
 #endif
@@ -2381,14 +2382,63 @@ static int device_help_func(QemuOpts *opts, void 
*opaque)
 return qdev_device_help(opts);
 }
 
+static int device_add_func(QemuOpts *opts, void *opaque)
+{
+DeviceState *dev;
+
+if (strcmp(qemu_opt_get(opts, "driver"), "memory") &&
+strcmp(qemu_opt_get(opts, "driver"), "cpu") &&
+opts->opaque == NULL) {
+dev = qdev_device_add(opts);
+if (!dev) {
+return -1;
+}
+object_unref(OBJECT(dev));
+}
+return 0;
+}
+
+static int device_create_func(QemuOpts *opts, void *opaque)
+{
+DeviceState *dev;
+
+dev = qdev_device_create(opts);
+
+return 0;
+}
+
 static int device_init_func(QemuOpts *opts, void *opaque)
 {
 DeviceState *dev;
+QEMUMachineInitArgs *current_machine = (QEMUMachineInitArgs *) opaque;
+DeviceState *intc = current_machine->intc;
 
-dev = qdev_device_add(opts);
-if (!dev)
-return -1;
-object_unref(OBJECT(dev));
+dev = qdev_device_init(opts, intc);
+
+if (dev && (dev->num_gpio_in > 32)) {
+/* Store the Interupt Controller */
+current_machine->intc = dev;
+}
+
+return 0;
+}
+
+static int device_connect_func(QemuOpts *opts, void *opaque)
+{
+DeviceState *dev;
+QEMUMachineInitArgs *current_machine = (QEMUMachineInitArgs *) opaque;
+DeviceState *intc = current_machine->intc;
+
+dev = qdev_device_connect(opts, intc);
+
+if (dev && (dev->num_gpio_in > 0)) {
+/* Store the Interupt Controller */
+current_machine->intc = dev;
+}
+
+if (dev) {
+object_unref(OBJECT(dev));
+}
 return 0;
 }
 
@@ -4377,11 +4427,21 @@ int main(int argc, char **argv, char **envp)
  .kernel_filename = kernel_filename,
  .kernel_cmdline = kernel_cmdline,
  .initrd_filename = initrd_filename,
- .cpu_model = cpu_model };
+ .cpu_model = cpu_model,
+ .intc = NULL };
 
 current_machine->init_args = args;
 machine->init(¤t_machine->init_args);
 
+/* Create devices */
+qemu_opts_foreach(qemu_find_opts("device"), device_create_func, NULL, 1);
+/* Init devices */
+qemu_opts_foreach(qemu_find_opts("device"), device_init_func,
+  ¤t_machine->init_args, 1);
+/* Init devices */
+qemu_opts_foreach(qemu_find_opts("device"), device_connect_func,
+  ¤t_machine->init_args, 1);
+
 audio_init();
 
 cpu_synchronize_all_post_init();
@@ -4395,8 +4455,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_add_func,
+  NULL, 1) != 0) {
 exit(1);
+}
 
 net_check_clients();
 
-- 
1.7.1




[Qemu-devel] [PATCH v2 0/4] Allow sysbus devices to be attached via commandline

2014-04-10 Thread Alistair Francis
This patch allows sysbus devices to be attached via
command line arguments.

This can be used to build an entire machine from the command
line or to just add devices that aren't in the machine_init
code.

A peripheral can be added with the following syntax:
-device cadence_uart,addr=0xE000,irq=27

A CPU can be added with either of the following:
-device cpu,model=cortex-a9,type=arm-cpu,reset-cbar=0xF8F0,midr=0x413   
 FC090
-sysbusdev device=cpu,name=microblaze-cp

RAM or ROM can be attached with this command:
-device memory,name=zynq.ext_ram,addr=0x,size=0x800

Multiple IRQ lines can be used as well as multiple properties:
-device pl330,addr=0xF8003000,irq=13,irq=14,irq=15,irq=16,irq=17,\
irq=40,irq=41,irq=42,irq=43,num_chnls=8,num_periph_req=4,num_events=16

This implementation uses a three round multi-pass method. This will
hopefully allow devices attached via the command line to be connected
to other command line devices (I haven't managed to get that working
yet though)

With Li Guang's blob loader implemented it is also possible to boot
images while using "-M none".

V2:
Use -device to attach the devices (Thanks Markus Armbruster)
Make the method much more generic
Allow CPUs and Memory to be attached via command line
Allow properties to be passed in via the command line

Thanks to Markus Armbruster and Peter Crosthwaite for
feedback on the first version


Alistair Francis (4):
  qemu-option.c: Add qemu_opt functions that step over arguments
  qdev-monitor: Implement three functions used to connect devices
  vl.c: Enable adding devices to the system bus
  qemu-options.hx: Update the command line documentation for -device

 include/hw/boards.h   |2 +
 include/monitor/qdev.h|3 +
 include/qemu/option.h |2 +
 include/qemu/option_int.h |1 +
 qdev-monitor.c|  237 -
 qemu-options.hx   |8 +-
 util/qemu-option.c|   30 ++
 vl.c  |   74 +-
 8 files changed, 346 insertions(+), 11 deletions(-)




[Qemu-devel] [PATCH v2 1/4] qemu-option.c: Add qemu_opt functions that step over arguments

2014-04-10 Thread Alistair Francis
This adds two functions, qemu_opt_step() and qemu_opt_name_step()
which iterate over the comma separated stings in the QemuOpts*
argument. This allows accessing multiple arguments with the
same name by iterating over all of the arguments

Signed-off-by: Alistair Francis 
---

 include/qemu/option.h |2 ++
 util/qemu-option.c|   30 ++
 2 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index 8c0ac34..ad20cd4 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -110,6 +110,8 @@ struct QemuOptsList {
 };
 
 const char *qemu_opt_get(QemuOpts *opts, const char *name);
+const char *qemu_opt_name_step(QemuOpts *opts, int num);
+const char *qemu_opt_step(QemuOpts *opts, int num);
 /**
  * qemu_opt_has_help_opt:
  * @opts: options to search for a help request
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 9d898af..4192c13 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -541,6 +541,36 @@ void print_option_help(QEMUOptionParameter *list)
 
 /* -- */
 
+const char *qemu_opt_name_step(QemuOpts *opts, int num)
+{
+QemuOpt *opt;
+int i = 0;
+
+QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
+if (i < num) {
+i++;
+continue;
+}
+return opt->name;
+}
+return NULL;
+}
+
+const char *qemu_opt_step(QemuOpts *opts, int num)
+{
+QemuOpt *opt;
+int i = 0;
+
+QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
+if (i < num) {
+i++;
+continue;
+}
+return opt->str;
+}
+return NULL;
+}
+
 static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
 {
 QemuOpt *opt;
-- 
1.7.1




Re: [Qemu-devel] [RFC PATCH v2 10/12] mc: expose tunable parameter for checkpointing frequency

2014-04-10 Thread Michael R. Hines

On 04/04/2014 10:56 PM, Eric Blake wrote:

On 04/03/2014 11:29 PM, Michael R. Hines wrote:

I'm trying to thing of a back-compat method, which exploits the fact
that we now have flat unions (something we didn't have when
migrate-set-capabilities was first added).  Maybe something like:

{ 'type': 'MigrationCapabilityBase',
'data': { 'capability': 'MigrationCapability' } }
{ 'type': 'MigrationCapabilityBool',
'data': { 'state': 'bool' } }
{ 'type': 'Migration CapabilityInt',
'data': { 'value': 'int' } }
{ 'union': 'MigrationCapabilityStatus',
'base': 'MigrationCapabilityBase',
'discriminator': 'capability',
'data': {
  'xbzrle': 'MigrationCapabilityBool',
  'auto-converge': 'MigrationCapabilityBool',
...
  'mc-delay': 'MigrationCapabilityInt'
} }

along with a tweak to query-migrate-capabilities for full back-compat:

# @query-migrate-capabilities
# @extended: #optional defaults to false; set to true to see non-boolean
capabilities (since 2.1)
{ 'command: 'query-migrate-capabilities',
'data': { '*extended': 'bool' },
'returns': ['MigrationCapabilityStatus'] }


I like this a lot - it's very complicated, but it is clean, I think.

Good - that means I made sense in trying to explain it.  And the more I
re-read my mail, the more I like the idea - fewer new commands, and make
the existing commands both more powerful and more easily extensible, all
while still being discoverable by libvirt without waiting for full
schema introspection.


Alright, I've saved this proposal on the wiki on the MicroCheckpointing
TODO section:

http://wiki.qemu.org/Features/MicroCheckpointing#TODO

For now, I've got several other issues to address before "someone"
gets around to this (I'd assume the maintainer or someone else would
want to test the 'extended' feature by itself in isolation with the existing
set of migration commands before someone else like me attempts to
use it or start adding new features to it.)

- Michael



[Qemu-devel] [PATCH v25 31/31] QemuOpts: cleanup tmp 'allocated' member from QemuOptsList

2014-04-10 Thread Chunyan Liu
Now only qemu_opts_append uses 'allocated' to indicate free memory.
For this function only, we can also let result list's (const char *)
members point to input list's members, only if the input list has
longer lifetime than result list. In current code, that is true.
So, we can remove the 'allocated' member from QemuOptsList definition
to keep code clean.

Signed-off-by: Chunyan Liu 
---
 include/qemu/option.h |  5 -
 util/qemu-option.c| 26 ++
 2 files changed, 2 insertions(+), 29 deletions(-)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index 0551beb..59bea75 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -63,11 +63,6 @@ typedef struct QemuOptDesc {
 } QemuOptDesc;
 
 struct QemuOptsList {
-/* FIXME: Temp used for QEMUOptionParamter->QemuOpts conversion to
- * indicate free memory. Will remove after all drivers switch to QemuOpts.
- */
-bool allocated;
-
 const char *name;
 const char *implied_opt_name;
 bool merge_lists;  /* Merge multiple uses of option into a single list? */
diff --git a/util/qemu-option.c b/util/qemu-option.c
index bf80b0d..9340cef 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -1076,26 +1076,12 @@ static size_t count_opts_list(QemuOptsList *list)
 
 void qemu_opts_free(QemuOptsList *list)
 {
-/* List members point to new malloced space and need to free.
- * FIXME:
- * Introduced for QEMUOptionParamter->QemuOpts conversion.
- * Will remove after all drivers switch to QemuOpts.
- */
-if (list && list->allocated) {
-QemuOptDesc *desc = list->desc;
-while (desc && desc->name) {
-g_free((char *)desc->name);
-g_free((char *)desc->help);
-g_free((char *)desc->def_value_str);
-desc++;
-}
-}
-
 g_free(list);
 }
 
 /* Realloc dst option list and append options from an option list (list)
  * to it. dst could be NULL or a malloced list.
+ * Result dst has shorter lifetime then input list.
  */
 QemuOptsList *qemu_opts_append(QemuOptsList *dst,
QemuOptsList *list)
@@ -1124,23 +1110,15 @@ QemuOptsList *qemu_opts_append(QemuOptsList *dst,
 dst->name = NULL;
 dst->implied_opt_name = NULL;
 QTAILQ_INIT(&dst->head);
-dst->allocated = true;
 }
 dst->desc[num_dst_opts].name = NULL;
 
-/* (const char *) members of result dst are malloced, need free. */
-assert(dst->allocated);
 /* append list->desc to dst->desc */
 if (list) {
 desc = list->desc;
 while (desc && desc->name) {
 if (find_desc_by_name(dst->desc, desc->name) == NULL) {
-dst->desc[num_dst_opts].name = g_strdup(desc->name);
-dst->desc[num_dst_opts].type = desc->type;
-dst->desc[num_dst_opts].help = g_strdup(desc->help);
-dst->desc[num_dst_opts].def_value_str =
- g_strdup(desc->def_value_str);
-num_dst_opts++;
+dst->desc[num_dst_opts++] = *desc;
 dst->desc[num_dst_opts].name = NULL;
 }
 desc++;
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 25/31] ssh.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/ssh.c | 32 +++-
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/block/ssh.c b/block/ssh.c
index aa63c9d..3a5eead 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -642,17 +642,20 @@ static int ssh_file_open(BlockDriverState *bs, QDict 
*options, int bdrv_flags,
 return ret;
 }
 
-static QEMUOptionParameter ssh_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size"
-},
-{ NULL }
+static QemuOptsList ssh_create_opts = {
+.name = "ssh-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(ssh_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+},
+{ /* end of list */ }
+}
 };
 
-static int ssh_create(const char *filename, QEMUOptionParameter *options,
-  Error **errp)
+static int ssh_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 int r, ret;
 Error *local_err = NULL;
@@ -665,12 +668,7 @@ static int ssh_create(const char *filename, 
QEMUOptionParameter *options,
 ssh_state_init(&s);
 
 /* Get desired file size. */
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-total_size = options->value.n;
-}
-options++;
-}
+total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
 DPRINTF("total_size=%" PRIi64, total_size);
 
 uri_options = qdict_new();
@@ -1044,14 +1042,14 @@ static BlockDriver bdrv_ssh = {
 .instance_size= sizeof(BDRVSSHState),
 .bdrv_parse_filename  = ssh_parse_filename,
 .bdrv_file_open   = ssh_file_open,
-.bdrv_create  = ssh_create,
+.bdrv_create2 = ssh_create,
 .bdrv_close   = ssh_close,
 .bdrv_has_zero_init   = ssh_has_zero_init,
 .bdrv_co_readv= ssh_co_readv,
 .bdrv_co_writev   = ssh_co_writev,
 .bdrv_getlength   = ssh_getlength,
 .bdrv_co_flush_to_disk= ssh_co_flush,
-.create_options   = ssh_create_options,
+.create_opts  = &ssh_create_opts,
 };
 
 static void bdrv_ssh_init(void)
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 30/31] cleanup QEMUOptionParameter

2014-04-10 Thread Chunyan Liu
Now that all backend drivers are using QemuOpts, remove all
QEMUOptionParameter related codes.

Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block.c   |  86 ++
 block/cow.c   |   4 +-
 block/gluster.c   |   8 +-
 block/iscsi.c |   2 +-
 block/nfs.c   |   2 +-
 block/qcow.c  |   4 +-
 block/qcow2.c |   6 +-
 block/qed.c   |   4 +-
 block/raw-posix.c |  10 +-
 block/raw-win32.c |   2 +-
 block/raw_bsd.c   |   4 +-
 block/rbd.c   |   2 +-
 block/sheepdog.c  |   6 +-
 block/ssh.c   |   2 +-
 block/vdi.c   |   2 +-
 block/vhdx.c  |   4 +-
 block/vmdk.c  |   6 +-
 block/vpc.c   |   2 +-
 block/vvfat.c |  12 +-
 include/block/block.h |   8 +-
 include/block/block_int.h |  16 +-
 include/qemu/option.h |  48 +-
 qemu-img.c|  19 +--
 util/qemu-option.c| 426 +-
 24 files changed, 68 insertions(+), 617 deletions(-)

diff --git a/block.c b/block.c
index 560cbd5..36c0e87 100644
--- a/block.c
+++ b/block.c
@@ -407,7 +407,6 @@ BlockDriver *bdrv_find_whitelisted_format(const char 
*format_name,
 typedef struct CreateCo {
 BlockDriver *drv;
 char *filename;
-QEMUOptionParameter *options;
 QemuOpts *opts;
 int ret;
 Error *err;
@@ -420,27 +419,8 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
 
 CreateCo *cco = opaque;
 assert(cco->drv);
-assert(!(cco->options && cco->opts));
-
-if (cco->drv->bdrv_create2) {
-QemuOptsList *opts_list = NULL;
-QemuOpts *opts = NULL;
-if (!cco->opts) {
-opts_list = params_to_opts(cco->options);
-cco->opts = opts =
-qemu_opts_create(opts_list, NULL, 0, &error_abort);
-}
-ret = cco->drv->bdrv_create2(cco->filename, cco->opts, &local_err);
-qemu_opts_del(opts);
-qemu_opts_free(opts_list);
-} else {
-QEMUOptionParameter *options = NULL;
-if (!cco->options) {
-cco->options = options = opts_to_params(cco->opts);
-}
-ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
-free_option_parameters(options);
-}
+
+ret = cco->drv->bdrv_create(cco->filename, cco->opts, &local_err);
 if (local_err) {
 error_propagate(&cco->err, local_err);
 }
@@ -448,7 +428,6 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
 }
 
 int bdrv_create(BlockDriver *drv, const char* filename,
-QEMUOptionParameter *options,
 QemuOpts *opts, Error **errp)
 {
 int ret;
@@ -457,13 +436,12 @@ int bdrv_create(BlockDriver *drv, const char* filename,
 CreateCo cco = {
 .drv = drv,
 .filename = g_strdup(filename),
-.options = options,
 .opts = opts,
 .ret = NOT_DONE,
 .err = NULL,
 };
 
-if (!drv->bdrv_create && !drv->bdrv_create2) {
+if (!drv->bdrv_create) {
 error_setg(errp, "Driver '%s' does not support image creation", 
drv->format_name);
 ret = -ENOTSUP;
 goto out;
@@ -494,8 +472,7 @@ out:
 return ret;
 }
 
-int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
- QemuOpts *opts, Error **errp)
+int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
 {
 BlockDriver *drv;
 Error *local_err = NULL;
@@ -507,7 +484,7 @@ int bdrv_create_file(const char* filename, 
QEMUOptionParameter *options,
 return -ENOENT;
 }
 
-ret = bdrv_create(drv, filename, options, opts, &local_err);
+ret = bdrv_create(drv, filename, opts, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 }
@@ -1196,7 +1173,6 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, 
Error **errp)
 
 int64_t total_size;
 BlockDriver *bdrv_qcow2;
-QemuOptsList *create_opts = NULL;
 QemuOpts *opts = NULL;
 QDict *snapshot_options;
 BlockDriverState *bs_snapshot;
@@ -1222,20 +1198,11 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, 
Error **errp)
 }
 
 bdrv_qcow2 = bdrv_find_format("qcow2");
-
-assert(!(bdrv_qcow2->create_options && bdrv_qcow2->create_opts));
-if (bdrv_qcow2->create_options) {
-create_opts = params_to_opts(bdrv_qcow2->create_options);
-} else {
-create_opts = bdrv_qcow2->create_opts;
-}
-opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
+opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0,
+&error_abort);
 qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
-ret = bdrv_create(bdrv_qcow2, tmp_filename, NULL, opts, &local_err);
+ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err);
 qemu_opts_del(opts);
-if (bdrv_qc

[Qemu-devel] [PATCH v25 27/31] vhdx.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/vhdx.c | 99 +---
 block/vhdx.h |  1 +
 2 files changed, 48 insertions(+), 52 deletions(-)

diff --git a/block/vhdx.c b/block/vhdx.c
index a9fcf6b..525becb 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -1716,8 +1716,7 @@ exit:
  *. ~ --- ~  ~  ~ ---.
  *   1MB
  */
-static int vhdx_create(const char *filename, QEMUOptionParameter *options,
-   Error **errp)
+static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 int ret = 0;
 uint64_t image_size = (uint64_t) 2 * GiB;
@@ -1730,24 +1729,15 @@ static int vhdx_create(const char *filename, 
QEMUOptionParameter *options,
 gunichar2 *creator = NULL;
 glong creator_items;
 BlockDriverState *bs;
-const char *type = NULL;
+char *type = NULL;
 VHDXImageType image_type;
 Error *local_err = NULL;
 
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-image_size = options->value.n;
-} else if (!strcmp(options->name, VHDX_BLOCK_OPT_LOG_SIZE)) {
-log_size = options->value.n;
-} else if (!strcmp(options->name, VHDX_BLOCK_OPT_BLOCK_SIZE)) {
-block_size = options->value.n;
-} else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
-type = options->value.s;
-} else if (!strcmp(options->name, VHDX_BLOCK_OPT_ZERO)) {
-use_zero_blocks = options->value.n != 0;
-}
-options++;
-}
+image_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+log_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_LOG_SIZE, 0);
+block_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_BLOCK_SIZE, 0);
+type = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
+use_zero_blocks = qemu_opt_get_bool_del(opts, VHDX_BLOCK_OPT_ZERO, false);
 
 if (image_size > VHDX_MAX_IMAGE_SIZE) {
 error_setg_errno(errp, EINVAL, "Image size too large; max of 64TB");
@@ -1756,7 +1746,7 @@ static int vhdx_create(const char *filename, 
QEMUOptionParameter *options,
 }
 
 if (type == NULL) {
-type = "dynamic";
+type = g_strdup("dynamic");
 }
 
 if (!strcmp(type, "dynamic")) {
@@ -1796,7 +1786,7 @@ static int vhdx_create(const char *filename, 
QEMUOptionParameter *options,
 block_size = block_size > VHDX_BLOCK_SIZE_MAX ? VHDX_BLOCK_SIZE_MAX :
 block_size;
 
-ret = bdrv_create_file(filename, options, NULL, &local_err);
+ret = bdrv_create_file(filename, NULL, opts, &local_err);
 if (ret < 0) {
 error_propagate(errp, local_err);
 goto exit;
@@ -1856,6 +1846,7 @@ static int vhdx_create(const char *filename, 
QEMUOptionParameter *options,
 delete_and_exit:
 bdrv_unref(bs);
 exit:
+g_free(type);
 g_free(creator);
 return ret;
 }
@@ -1878,37 +1869,41 @@ static int vhdx_check(BlockDriverState *bs, 
BdrvCheckResult *result,
 return 0;
 }
 
-static QEMUOptionParameter vhdx_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size; max of 64TB."
-},
-{
-.name = VHDX_BLOCK_OPT_LOG_SIZE,
-.type = OPT_SIZE,
-.value.n = 1 * MiB,
-.help = "Log size; min 1MB."
-},
-{
-.name = VHDX_BLOCK_OPT_BLOCK_SIZE,
-.type = OPT_SIZE,
-.value.n = 0,
-.help = "Block Size; min 1MB, max 256MB. " \
-"0 means auto-calculate based on image size."
-},
-{
-.name = BLOCK_OPT_SUBFMT,
-.type = OPT_STRING,
-.help = "VHDX format type, can be either 'dynamic' or 'fixed'. "\
-"Default is 'dynamic'."
-},
-{
-.name = VHDX_BLOCK_OPT_ZERO,
-.type = OPT_FLAG,
-.help = "Force use of payload blocks of type 'ZERO'.  Non-standard."
-},
-{ NULL }
+static QemuOptsList vhdx_create_opts = {
+.name = "vhdx-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(vhdx_create_opts.head),
+.desc = {
+{
+   .name = BLOCK_OPT_SIZE,
+   .type = QEMU_OPT_SIZE,
+   .help = "Virtual disk size; max of 64TB."
+   },
+   {
+   .name = VHDX_BLOCK_OPT_LOG_SIZE,
+   .type = QEMU_OPT_SIZE,
+   .def_value_str = stringify(DEFAULT_LOG_SIZE),
+   .help = "Log size; min 1MB."
+   },
+   {
+   .name = VHDX_BLOCK_OPT_BLOCK_SIZE,
+   .type = QEMU_OPT_SIZE,
+   .def_value_str = stringify(0),
+   .help = "Block Size; min 1MB, max 256MB. " \
+   "0 means auto-calculate based on image size."
+   },
+   {
+   .name = BLOCK_OPT_SUBFMT,
+   .type = QEMU_OPT_STRING,
+   .help = "VHDX format type, can be either 'dynamic' or 'fixed

[Qemu-devel] [PATCH v25 21/31] raw-win32.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/raw-win32.c | 38 +++---
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/block/raw-win32.c b/block/raw-win32.c
index 48cb2c2..b00d7fc 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -475,8 +475,7 @@ static int64_t raw_get_allocated_file_size(BlockDriverState 
*bs)
 return st.st_size;
 }
 
-static int raw_create(const char *filename, QEMUOptionParameter *options,
-  Error **errp)
+static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 int fd;
 int64_t total_size = 0;
@@ -484,12 +483,8 @@ static int raw_create(const char *filename, 
QEMUOptionParameter *options,
 strstart(filename, "file:", &filename);
 
 /* Read out options */
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-total_size = options->value.n / 512;
-}
-options++;
-}
+total_size =
+qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
 
 fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
@@ -503,13 +498,18 @@ static int raw_create(const char *filename, 
QEMUOptionParameter *options,
 return 0;
 }
 
-static QEMUOptionParameter raw_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size"
-},
-{ NULL }
+
+static QemuOptsList raw_create_opts = {
+.name = "raw-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+},
+{ /* end of list */ }
+}
 };
 
 static BlockDriver bdrv_file = {
@@ -518,9 +518,9 @@ static BlockDriver bdrv_file = {
 .instance_size = sizeof(BDRVRawState),
 .bdrv_needs_filename = true,
 .bdrv_parse_filename = raw_parse_filename,
-.bdrv_file_open= raw_open,
-.bdrv_close= raw_close,
-.bdrv_create   = raw_create,
+.bdrv_file_open = raw_open,
+.bdrv_close = raw_close,
+.bdrv_create2   = raw_create,
 .bdrv_has_zero_init = bdrv_has_zero_init_1,
 
 .bdrv_aio_readv = raw_aio_readv,
@@ -532,7 +532,7 @@ static BlockDriver bdrv_file = {
 .bdrv_get_allocated_file_size
 = raw_get_allocated_file_size,
 
-.create_options = raw_create_options,
+.create_opts= &raw_create_opts,
 };
 
 /***/
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 29/31] vpc.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/vpc.c | 62 +
 1 file changed, 34 insertions(+), 28 deletions(-)

diff --git a/block/vpc.c b/block/vpc.c
index 2e25f57..8ebf424 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -738,12 +738,11 @@ static int create_fixed_disk(int fd, uint8_t *buf, 
int64_t total_size)
 return ret;
 }
 
-static int vpc_create(const char *filename, QEMUOptionParameter *options,
-  Error **errp)
+static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 uint8_t buf[1024];
 VHDFooter *footer = (VHDFooter *) buf;
-QEMUOptionParameter *disk_type_param;
+char *disk_type_param;
 int fd, i;
 uint16_t cyls = 0;
 uint8_t heads = 0;
@@ -754,16 +753,16 @@ static int vpc_create(const char *filename, 
QEMUOptionParameter *options,
 int ret = -EIO;
 
 /* Read out options */
-total_size = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n;
-
-disk_type_param = get_option_parameter(options, BLOCK_OPT_SUBFMT);
-if (disk_type_param && disk_type_param->value.s) {
-if (!strcmp(disk_type_param->value.s, "dynamic")) {
+total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+disk_type_param = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
+if (disk_type_param) {
+if (!strcmp(disk_type_param, "dynamic")) {
 disk_type = VHD_DYNAMIC;
-} else if (!strcmp(disk_type_param->value.s, "fixed")) {
+} else if (!strcmp(disk_type_param, "fixed")) {
 disk_type = VHD_FIXED;
 } else {
-return -EINVAL;
+ret = -EINVAL;
+goto out;
 }
 } else {
 disk_type = VHD_DYNAMIC;
@@ -772,7 +771,8 @@ static int vpc_create(const char *filename, 
QEMUOptionParameter *options,
 /* Create the file */
 fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
 if (fd < 0) {
-return -EIO;
+ret = -EIO;
+goto out;
 }
 
 /*
@@ -837,8 +837,10 @@ static int vpc_create(const char *filename, 
QEMUOptionParameter *options,
 ret = create_fixed_disk(fd, buf, total_size);
 }
 
- fail:
+fail:
 qemu_close(fd);
+out:
+g_free(disk_type_param);
 return ret;
 }
 
@@ -866,20 +868,24 @@ static void vpc_close(BlockDriverState *bs)
 error_free(s->migration_blocker);
 }
 
-static QEMUOptionParameter vpc_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size"
-},
-{
-.name = BLOCK_OPT_SUBFMT,
-.type = OPT_STRING,
-.help =
-"Type of virtual hard disk format. Supported formats are "
-"{dynamic (default) | fixed} "
-},
-{ NULL }
+static QemuOptsList vpc_create_opts = {
+.name = "vpc-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(vpc_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+},
+{
+.name = BLOCK_OPT_SUBFMT,
+.type = QEMU_OPT_STRING,
+.help =
+"Type of virtual hard disk format. Supported formats are "
+"{dynamic (default) | fixed} "
+},
+{ /* end of list */ }
+}
 };
 
 static BlockDriver bdrv_vpc = {
@@ -890,14 +896,14 @@ static BlockDriver bdrv_vpc = {
 .bdrv_open  = vpc_open,
 .bdrv_close = vpc_close,
 .bdrv_reopen_prepare= vpc_reopen_prepare,
-.bdrv_create= vpc_create,
+.bdrv_create2   = vpc_create,
 
 .bdrv_read  = vpc_co_read,
 .bdrv_write = vpc_co_write,
 
 .bdrv_get_info  = vpc_get_info,
 
-.create_options = vpc_create_options,
+.create_opts= &vpc_create_opts,
 .bdrv_has_zero_init = vpc_has_zero_init,
 };
 
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 18/31] qcow2.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/qcow2.c | 265 +++---
 include/qemu/option.h |   1 +
 util/qemu-option.c|   2 +-
 3 files changed, 143 insertions(+), 125 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 49985e3..96c78df 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -31,6 +31,7 @@
 #include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qbool.h"
 #include "trace.h"
+#include "qemu/option_int.h"
 
 /*
   Differences with QCOW:
@@ -1593,7 +1594,7 @@ static int preallocate(BlockDriverState *bs)
 static int qcow2_create2(const char *filename, int64_t total_size,
  const char *backing_file, const char *backing_format,
  int flags, size_t cluster_size, int prealloc,
- QEMUOptionParameter *options, int version,
+ QemuOpts *opts, int version,
  Error **errp)
 {
 /* Calculate cluster_bits */
@@ -1625,7 +1626,7 @@ static int qcow2_create2(const char *filename, int64_t 
total_size,
 Error *local_err = NULL;
 int ret;
 
-ret = bdrv_create_file(filename, options, NULL, &local_err);
+ret = bdrv_create_file(filename, NULL, opts, &local_err);
 if (ret < 0) {
 error_propagate(errp, local_err);
 return ret;
@@ -1761,11 +1762,11 @@ out:
 return ret;
 }
 
-static int qcow2_create(const char *filename, QEMUOptionParameter *options,
-Error **errp)
+static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
 {
-const char *backing_file = NULL;
-const char *backing_fmt = NULL;
+char *backing_file = NULL;
+char *backing_fmt = NULL;
+char *buf = NULL;
 uint64_t sectors = 0;
 int flags = 0;
 size_t cluster_size = DEFAULT_CLUSTER_SIZE;
@@ -1775,64 +1776,66 @@ static int qcow2_create(const char *filename, 
QEMUOptionParameter *options,
 int ret;
 
 /* Read out options */
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-sectors = options->value.n / 512;
-} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-backing_file = options->value.s;
-} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) {
-backing_fmt = options->value.s;
-} else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
-flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
-} else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
-if (options->value.n) {
-cluster_size = options->value.n;
-}
-} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
-if (!options->value.s || !strcmp(options->value.s, "off")) {
-prealloc = 0;
-} else if (!strcmp(options->value.s, "metadata")) {
-prealloc = 1;
-} else {
-error_setg(errp, "Invalid preallocation mode: '%s'",
-   options->value.s);
-return -EINVAL;
-}
-} else if (!strcmp(options->name, BLOCK_OPT_COMPAT_LEVEL)) {
-if (!options->value.s) {
-/* keep the default */
-} else if (!strcmp(options->value.s, "0.10")) {
-version = 2;
-} else if (!strcmp(options->value.s, "1.1")) {
-version = 3;
-} else {
-error_setg(errp, "Invalid compatibility level: '%s'",
-   options->value.s);
-return -EINVAL;
-}
-} else if (!strcmp(options->name, BLOCK_OPT_LAZY_REFCOUNTS)) {
-flags |= options->value.n ? BLOCK_FLAG_LAZY_REFCOUNTS : 0;
-}
-options++;
+sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
+backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
+backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
+if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
+flags |= BLOCK_FLAG_ENCRYPT;
+}
+cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
+ DEFAULT_CLUSTER_SIZE);
+buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
+if (!buf || !strcmp(buf, "off")) {
+prealloc = 0;
+} else if (!strcmp(buf, "metadata")) {
+prealloc = 1;
+} else {
+error_setg(errp, "Invalid preallocation mode: '%s'", buf);
+ret = -EINVAL;
+goto finish;
+}
+g_free(buf);
+buf = qemu_opt_get_del(opts, BLOCK_OPT_COMPAT_LEVEL);
+if (!buf) {
+/* keep the default */
+} else if (!strcmp(buf, "0.10")) {
+version = 2;
+} else if (!strcmp(buf, "1.1")) {
+version = 3;
+} else {
+error_setg(errp, "Invalid compatibility level: '%s'", buf);
+ret = -EINVAL;
+goto finish;
+}
+
+   

[Qemu-devel] [PATCH v25 28/31] vmdk.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/vmdk.c | 123 ++-
 1 file changed, 63 insertions(+), 60 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index d87c8f6..f9b68a0 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1681,17 +1681,16 @@ static int filename_decompose(const char *filename, 
char *path, char *prefix,
 return VMDK_OK;
 }
 
-static int vmdk_create(const char *filename, QEMUOptionParameter *options,
-   Error **errp)
+static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 int idx = 0;
 BlockDriverState *new_bs = NULL;
 Error *local_err;
 char *desc = NULL;
 int64_t total_size = 0, filesize;
-const char *adapter_type = NULL;
-const char *backing_file = NULL;
-const char *fmt = NULL;
+char *adapter_type = NULL;
+char *backing_file = NULL;
+char *fmt = NULL;
 int flags = 0;
 int ret = 0;
 bool flat, split, compress;
@@ -1731,24 +1730,19 @@ static int vmdk_create(const char *filename, 
QEMUOptionParameter *options,
 goto exit;
 }
 /* Read out options */
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-total_size = options->value.n;
-} else if (!strcmp(options->name, BLOCK_OPT_ADAPTER_TYPE)) {
-adapter_type = options->value.s;
-} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-backing_file = options->value.s;
-} else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
-flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0;
-} else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
-fmt = options->value.s;
-} else if (!strcmp(options->name, BLOCK_OPT_ZEROED_GRAIN)) {
-zeroed_grain |= options->value.n;
-}
-options++;
+total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE);
+backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
+if (qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false)) {
+flags |= BLOCK_FLAG_COMPAT6;
+}
+fmt = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
+if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false)) {
+zeroed_grain = true;
 }
+
 if (!adapter_type) {
-adapter_type = "ide";
+adapter_type = g_strdup("ide");
 } else if (strcmp(adapter_type, "ide") &&
strcmp(adapter_type, "buslogic") &&
strcmp(adapter_type, "lsilogic") &&
@@ -1764,7 +1758,7 @@ static int vmdk_create(const char *filename, 
QEMUOptionParameter *options,
 }
 if (!fmt) {
 /* Default format to monolithicSparse */
-fmt = "monolithicSparse";
+fmt = g_strdup("monolithicSparse");
 } else if (strcmp(fmt, "monolithicFlat") &&
strcmp(fmt, "monolithicSparse") &&
strcmp(fmt, "twoGbMaxExtentSparse") &&
@@ -1865,7 +1859,7 @@ static int vmdk_create(const char *filename, 
QEMUOptionParameter *options,
 if (!split && !flat) {
 desc_offset = 0x200;
 } else {
-ret = bdrv_create_file(filename, options, NULL, &local_err);
+ret = bdrv_create_file(filename, NULL, opts, &local_err);
 if (ret < 0) {
 error_setg_errno(errp, -ret, "Could not create image file");
 goto exit;
@@ -1895,6 +1889,9 @@ exit:
 if (new_bs) {
 bdrv_unref(new_bs);
 }
+g_free(adapter_type);
+g_free(backing_file);
+g_free(fmt);
 g_free(desc);
 g_string_free(ext_desc_lines, true);
 return ret;
@@ -2062,41 +2059,47 @@ static ImageInfoSpecific 
*vmdk_get_specific_info(BlockDriverState *bs)
 return spec_info;
 }
 
-static QEMUOptionParameter vmdk_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size"
-},
-{
-.name = BLOCK_OPT_ADAPTER_TYPE,
-.type = OPT_STRING,
-.help = "Virtual adapter type, can be one of "
-"ide (default), lsilogic, buslogic or legacyESX"
-},
-{
-.name = BLOCK_OPT_BACKING_FILE,
-.type = OPT_STRING,
-.help = "File name of a base image"
-},
-{
-.name = BLOCK_OPT_COMPAT6,
-.type = OPT_FLAG,
-.help = "VMDK version 6 image"
-},
-{
-.name = BLOCK_OPT_SUBFMT,
-.type = OPT_STRING,
-.help =
-"VMDK flat extent format, can be one of "
-"{monolithicSparse (default) | monolithicFlat | 
twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} "
-},
-{
-.name = BLOCK_OPT_ZEROED_GRAIN,
-.type = OPT_FLAG,
-.help = "Enable efficient zero writes using the zeroed-grain GTE 
feature"
-},
-{ NULL }
+static QemuOptsList vmdk_create_opts =

[Qemu-devel] [PATCH v25 24/31] sheepdog.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/sheepdog.c | 108 ---
 1 file changed, 55 insertions(+), 53 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 0eb33ee..9f280f6 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -1626,12 +1626,13 @@ static int parse_redundancy(BDRVSheepdogState *s, const 
char *opt)
 return 0;
 }
 
-static int sd_create(const char *filename, QEMUOptionParameter *options,
+static int sd_create(const char *filename, QemuOpts *opts,
  Error **errp)
 {
 int ret = 0;
 uint32_t vid = 0;
 char *backing_file = NULL;
+char *buf = NULL;
 BDRVSheepdogState *s;
 char tag[SD_MAX_VDI_TAG_LEN];
 uint32_t snapid;
@@ -1650,31 +1651,26 @@ static int sd_create(const char *filename, 
QEMUOptionParameter *options,
 goto out;
 }
 
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-s->inode.vdi_size = options->value.n;
-} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-backing_file = options->value.s;
-} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
-if (!options->value.s || !strcmp(options->value.s, "off")) {
-prealloc = false;
-} else if (!strcmp(options->value.s, "full")) {
-prealloc = true;
-} else {
-error_report("Invalid preallocation mode: '%s'",
- options->value.s);
-ret = -EINVAL;
-goto out;
-}
-} else if (!strcmp(options->name, BLOCK_OPT_REDUNDANCY)) {
-if (options->value.s) {
-ret = parse_redundancy(s, options->value.s);
-if (ret < 0) {
-goto out;
-}
-}
+s->inode.vdi_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
+buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
+if (!buf || !strcmp(buf, "off")) {
+prealloc = false;
+} else if (!strcmp(buf, "full")) {
+prealloc = true;
+} else {
+error_report("Invalid preallocation mode: '%s'", buf);
+ret = -EINVAL;
+goto out;
+}
+
+g_free(buf);
+buf = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY);
+if (buf) {
+ret = parse_redundancy(s, buf);
+if (ret < 0) {
+goto out;
 }
-options++;
 }
 
 if (s->inode.vdi_size > SD_MAX_VDI_SIZE) {
@@ -1724,6 +1720,8 @@ static int sd_create(const char *filename, 
QEMUOptionParameter *options,
 
 ret = sd_prealloc(filename);
 out:
+g_free(backing_file);
+g_free(buf);
 g_free(s);
 return ret;
 }
@@ -2490,28 +2488,32 @@ static int64_t 
sd_get_allocated_file_size(BlockDriverState *bs)
 return size;
 }
 
-static QEMUOptionParameter sd_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size"
-},
-{
-.name = BLOCK_OPT_BACKING_FILE,
-.type = OPT_STRING,
-.help = "File name of a base image"
-},
-{
-.name = BLOCK_OPT_PREALLOC,
-.type = OPT_STRING,
-.help = "Preallocation mode (allowed values: off, full)"
-},
-{
-.name = BLOCK_OPT_REDUNDANCY,
-.type = OPT_STRING,
-.help = "Redundancy of the image"
-},
-{ NULL }
+static QemuOptsList sd_create_opts = {
+.name = "sheepdog-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(sd_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+},
+{
+.name = BLOCK_OPT_BACKING_FILE,
+.type = QEMU_OPT_STRING,
+.help = "File name of a base image"
+},
+{
+.name = BLOCK_OPT_PREALLOC,
+.type = QEMU_OPT_STRING,
+.help = "Preallocation mode (allowed values: off, full)"
+},
+{
+.name = BLOCK_OPT_REDUNDANCY,
+.type = QEMU_OPT_STRING,
+.help = "Redundancy of the image"
+},
+{ /* end of list */ }
+}
 };
 
 static BlockDriver bdrv_sheepdog = {
@@ -2521,7 +2523,7 @@ static BlockDriver bdrv_sheepdog = {
 .bdrv_needs_filename = true,
 .bdrv_file_open = sd_open,
 .bdrv_close = sd_close,
-.bdrv_create= sd_create,
+.bdrv_create2   = sd_create,
 .bdrv_has_zero_init = bdrv_has_zero_init_1,
 .bdrv_getlength = sd_getlength,
 .bdrv_get_allocated_file_size = sd_get_allocated_file_size,
@@ -2541,7 +2543,7 @@ static BlockDriver bdrv_sheepdog = {
 .bdrv_save_vmstate  = sd_save_vmstate,
 .bdrv_load_vmstate  = sd_load_vmstate,
 
-.create_options = sd_create_options,

[Qemu-devel] [PATCH v25 16/31] nfs.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Signed-off-by: Chunyan Liu 
---
 block/nfs.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/block/nfs.c b/block/nfs.c
index 98aa363..664ceeb 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -357,20 +357,14 @@ static int nfs_file_open(BlockDriverState *bs, QDict 
*options, int flags,
 return 0;
 }
 
-static int nfs_file_create(const char *url, QEMUOptionParameter *options,
-   Error **errp)
+static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp)
 {
 int ret = 0;
 int64_t total_size = 0;
 NFSClient *client = g_malloc0(sizeof(NFSClient));
 
 /* Read out options */
-while (options && options->name) {
-if (!strcmp(options->name, "size")) {
-total_size = options->value.n;
-}
-options++;
-}
+total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
 
 ret = nfs_client_open(client, url, O_CREAT, errp);
 if (ret < 0) {
@@ -427,7 +421,7 @@ static BlockDriver bdrv_nfs = {
 
 .bdrv_file_open  = nfs_file_open,
 .bdrv_close  = nfs_file_close,
-.bdrv_create = nfs_file_create,
+.bdrv_create2= nfs_file_create,
 
 .bdrv_co_readv = nfs_co_readv,
 .bdrv_co_writev= nfs_co_writev,
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 26/31] vdi.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/vdi.c | 73 +
 1 file changed, 35 insertions(+), 38 deletions(-)

diff --git a/block/vdi.c b/block/vdi.c
index 820cd37..950cf46 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -672,8 +672,7 @@ static int vdi_co_write(BlockDriverState *bs,
 return ret;
 }
 
-static int vdi_create(const char *filename, QEMUOptionParameter *options,
-  Error **errp)
+static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 int fd;
 int result = 0;
@@ -688,25 +687,18 @@ static int vdi_create(const char *filename, 
QEMUOptionParameter *options,
 logout("\n");
 
 /* Read out options. */
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-bytes = options->value.n;
+bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
 #if defined(CONFIG_VDI_BLOCK_SIZE)
-} else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
-if (options->value.n) {
-/* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */
-block_size = options->value.n;
-}
+/* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */
+block_size = qemu_opt_get_size_del(opts,
+   BLOCK_OPT_CLUSTER_SIZE,
+   DEFAULT_CLUSTER_SIZE);
 #endif
 #if defined(CONFIG_VDI_STATIC_IMAGE)
-} else if (!strcmp(options->name, BLOCK_OPT_STATIC)) {
-if (options->value.n) {
-image_type = VDI_TYPE_STATIC;
-}
-#endif
-}
-options++;
+if (qemu_opt_get_bool_del(opts, BLOCK_OPT_STATIC, false)) {
+image_type = VDI_TYPE_STATIC;
 }
+#endif
 
 if (bytes > VDI_DISK_SIZE_MAX) {
 result = -ENOTSUP;
@@ -796,29 +788,34 @@ static void vdi_close(BlockDriverState *bs)
 error_free(s->migration_blocker);
 }
 
-static QEMUOptionParameter vdi_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size"
-},
+static QemuOptsList vdi_create_opts = {
+.name = "vdi-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(vdi_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+},
 #if defined(CONFIG_VDI_BLOCK_SIZE)
-{
-.name = BLOCK_OPT_CLUSTER_SIZE,
-.type = OPT_SIZE,
-.help = "VDI cluster (block) size",
-.value = { .n = DEFAULT_CLUSTER_SIZE },
-},
+{
+.name = BLOCK_OPT_CLUSTER_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "VDI cluster (block) size",
+.def_value_str = stringify(DEFAULT_CLUSTER_SIZE)
+},
 #endif
 #if defined(CONFIG_VDI_STATIC_IMAGE)
-{
-.name = BLOCK_OPT_STATIC,
-.type = OPT_FLAG,
-.help = "VDI static (pre-allocated) image"
-},
+{
+.name = BLOCK_OPT_STATIC,
+.type = QEMU_OPT_BOOL,
+.help = "VDI static (pre-allocated) image",
+.def_value_str = "off"
+},
 #endif
-/* TODO: An additional option to set UUID values might be useful. */
-{ NULL }
+/* TODO: An additional option to set UUID values might be useful. */
+{ /* end of list */ }
+}
 };
 
 static BlockDriver bdrv_vdi = {
@@ -828,7 +825,7 @@ static BlockDriver bdrv_vdi = {
 .bdrv_open = vdi_open,
 .bdrv_close = vdi_close,
 .bdrv_reopen_prepare = vdi_reopen_prepare,
-.bdrv_create = vdi_create,
+.bdrv_create2 = vdi_create,
 .bdrv_has_zero_init = bdrv_has_zero_init_1,
 .bdrv_co_get_block_status = vdi_co_get_block_status,
 .bdrv_make_empty = vdi_make_empty,
@@ -840,7 +837,7 @@ static BlockDriver bdrv_vdi = {
 
 .bdrv_get_info = vdi_get_info,
 
-.create_options = vdi_create_options,
+.create_opts = &vdi_create_opts,
 .bdrv_check = vdi_check,
 };
 
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 19/31] qed.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
One extra change is to define QED_DEFAULT_CLUSTER_SIZE = 65536 instead
of 64 * 1024; because:
according to existing create_options, "cluster size" has default value =
QED_DEFAULT_CLUSTER_SIZE, after switching to create_opts, this has to be
stringized and set to .def_value_str. That is,
  .def_value_str = stringify(QED_DEFAULT_CLUSTER_SIZE),
so the QED_DEFAULT_CLUSTER_SIZE could not be a expression.

Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/qed.c | 114 
 block/qed.h |   3 +-
 2 files changed, 61 insertions(+), 56 deletions(-)

diff --git a/block/qed.c b/block/qed.c
index ef5c56c..ae7b98f 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -621,53 +621,51 @@ out:
 return ret;
 }
 
-static int bdrv_qed_create(const char *filename, QEMUOptionParameter *options,
-   Error **errp)
+static int bdrv_qed_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 uint64_t image_size = 0;
 uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE;
 uint32_t table_size = QED_DEFAULT_TABLE_SIZE;
-const char *backing_file = NULL;
-const char *backing_fmt = NULL;
-
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-image_size = options->value.n;
-} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-backing_file = options->value.s;
-} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) {
-backing_fmt = options->value.s;
-} else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
-if (options->value.n) {
-cluster_size = options->value.n;
-}
-} else if (!strcmp(options->name, BLOCK_OPT_TABLE_SIZE)) {
-if (options->value.n) {
-table_size = options->value.n;
-}
-}
-options++;
-}
+char *backing_file = NULL;
+char *backing_fmt = NULL;
+int ret;
+
+image_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
+backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
+cluster_size = qemu_opt_get_size_del(opts,
+ BLOCK_OPT_CLUSTER_SIZE,
+ QED_DEFAULT_CLUSTER_SIZE);
+table_size = qemu_opt_get_size_del(opts, BLOCK_OPT_TABLE_SIZE,
+   QED_DEFAULT_TABLE_SIZE);
 
 if (!qed_is_cluster_size_valid(cluster_size)) {
 fprintf(stderr, "QED cluster size must be within range [%u, %u] and 
power of 2\n",
 QED_MIN_CLUSTER_SIZE, QED_MAX_CLUSTER_SIZE);
-return -EINVAL;
+ret = -EINVAL;
+goto finish;
 }
 if (!qed_is_table_size_valid(table_size)) {
 fprintf(stderr, "QED table size must be within range [%u, %u] and 
power of 2\n",
 QED_MIN_TABLE_SIZE, QED_MAX_TABLE_SIZE);
-return -EINVAL;
+ret = -EINVAL;
+goto finish;
 }
 if (!qed_is_image_size_valid(image_size, cluster_size, table_size)) {
 fprintf(stderr, "QED image size must be a non-zero multiple of "
 "cluster size and less than %" PRIu64 " bytes\n",
 qed_max_image_size(cluster_size, table_size));
-return -EINVAL;
+ret = -EINVAL;
+goto finish;
 }
 
-return qed_create(filename, cluster_size, image_size, table_size,
-  backing_file, backing_fmt, errp);
+ret = qed_create(filename, cluster_size, image_size, table_size,
+ backing_file, backing_fmt, errp);
+
+finish:
+g_free(backing_file);
+g_free(backing_fmt);
+return ret;
 }
 
 typedef struct {
@@ -1593,43 +1591,51 @@ static int bdrv_qed_check(BlockDriverState *bs, 
BdrvCheckResult *result,
 return qed_check(s, result, !!fix);
 }
 
-static QEMUOptionParameter qed_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size (in bytes)"
-}, {
-.name = BLOCK_OPT_BACKING_FILE,
-.type = OPT_STRING,
-.help = "File name of a base image"
-}, {
-.name = BLOCK_OPT_BACKING_FMT,
-.type = OPT_STRING,
-.help = "Image format of the base image"
-}, {
-.name = BLOCK_OPT_CLUSTER_SIZE,
-.type = OPT_SIZE,
-.help = "Cluster size (in bytes)",
-.value = { .n = QED_DEFAULT_CLUSTER_SIZE },
-}, {
-.name = BLOCK_OPT_TABLE_SIZE,
-.type = OPT_SIZE,
-.help = "L1/L2 table size (in clusters)"
-},
-{ /* end of list */ }
+static QemuOptsList qed_create_opts = {
+.name = "qed-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(qed_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+

[Qemu-devel] [PATCH v25 12/31] vvfat.c: handle cross_driver's create_options and create_opts

2014-04-10 Thread Chunyan Liu
vvfat shares create options of qcow driver. To avoid vvfat broken when
qcow driver changes from QEMUOptionParameter to QemuOpts, let it able
to handle both cases.

Signed-off-by: Chunyan Liu 
---
 block/vvfat.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index 4390b12..e91cb21 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2907,7 +2907,8 @@ static BlockDriver vvfat_write_target = {
 static int enable_write_target(BDRVVVFATState *s)
 {
 BlockDriver *bdrv_qcow;
-QEMUOptionParameter *options;
+QemuOptsList *create_opts = NULL;
+QemuOpts *opts = NULL;
 Error *local_err = NULL;
 int ret;
 int size = sector2cluster(s, s->sector_count);
@@ -2922,11 +2923,17 @@ static int enable_write_target(BDRVVVFATState *s)
 }
 
 bdrv_qcow = bdrv_find_format("qcow");
-options = parse_option_parameters("", bdrv_qcow->create_options, NULL);
-set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
-set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");
+assert(!(bdrv_qcow->create_opts && bdrv_qcow->create_options));
+if (bdrv_qcow->create_options) {
+create_opts = params_to_opts(bdrv_qcow->create_options);
+} else {
+create_opts = bdrv_qcow->create_opts;
+}
+opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512);
+qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:");
 
-ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, NULL, &local_err);
+ret = bdrv_create(bdrv_qcow, s->qcow_filename, NULL, opts, &local_err);
 if (ret < 0) {
 qerror_report_err(local_err);
 error_free(local_err);
@@ -2955,6 +2962,8 @@ static int enable_write_target(BDRVVVFATState *s)
 return 0;
 
 err:
+qemu_opts_del(opts);
+qemu_opts_free(create_opts);
 g_free(s->qcow_filename);
 s->qcow_filename = NULL;
 return ret;
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 23/31] rbd.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/rbd.c | 63 +
 1 file changed, 30 insertions(+), 33 deletions(-)

diff --git a/block/rbd.c b/block/rbd.c
index dbc79f4..f878877 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -282,8 +282,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char 
*conf)
 return ret;
 }
 
-static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options,
-   Error **errp)
+static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 int64_t bytes = 0;
 int64_t objsize;
@@ -306,24 +305,18 @@ static int qemu_rbd_create(const char *filename, 
QEMUOptionParameter *options,
 }
 
 /* Read out options */
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-bytes = options->value.n;
-} else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
-if (options->value.n) {
-objsize = options->value.n;
-if ((objsize - 1) & objsize) {/* not a power of 2? */
-error_report("obj size needs to be power of 2");
-return -EINVAL;
-}
-if (objsize < 4096) {
-error_report("obj size too small");
-return -EINVAL;
-}
-obj_order = ffs(objsize) - 1;
-}
+bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+objsize = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, 0);
+if (objsize) {
+if ((objsize - 1) & objsize) {/* not a power of 2? */
+error_report("obj size needs to be power of 2");
+return -EINVAL;
+}
+if (objsize < 4096) {
+error_report("obj size too small");
+return -EINVAL;
 }
-options++;
+obj_order = ffs(objsize) - 1;
 }
 
 clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
@@ -900,18 +893,22 @@ static BlockDriverAIOCB* 
qemu_rbd_aio_discard(BlockDriverState *bs,
 }
 #endif
 
-static QEMUOptionParameter qemu_rbd_create_options[] = {
-{
- .name = BLOCK_OPT_SIZE,
- .type = OPT_SIZE,
- .help = "Virtual disk size"
-},
-{
- .name = BLOCK_OPT_CLUSTER_SIZE,
- .type = OPT_SIZE,
- .help = "RBD object size"
-},
-{NULL}
+static QemuOptsList qemu_rbd_create_opts = {
+.name = "rbd-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(qemu_rbd_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+},
+{
+.name = BLOCK_OPT_CLUSTER_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "RBD object size"
+},
+{ /* end of list */ }
+}
 };
 
 static BlockDriver bdrv_rbd = {
@@ -920,10 +917,10 @@ static BlockDriver bdrv_rbd = {
 .bdrv_needs_filename = true,
 .bdrv_file_open = qemu_rbd_open,
 .bdrv_close = qemu_rbd_close,
-.bdrv_create= qemu_rbd_create,
+.bdrv_create2   = qemu_rbd_create,
 .bdrv_has_zero_init = bdrv_has_zero_init_1,
 .bdrv_get_info  = qemu_rbd_getinfo,
-.create_options = qemu_rbd_create_options,
+.create_opts= &qemu_rbd_create_opts,
 .bdrv_getlength = qemu_rbd_getlength,
 .bdrv_truncate  = qemu_rbd_truncate,
 .protocol_name  = "rbd",
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 17/31] qcow.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/qcow.c | 72 ++--
 1 file changed, 36 insertions(+), 36 deletions(-)

diff --git a/block/qcow.c b/block/qcow.c
index 9411aef..b4ce133 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -662,35 +662,29 @@ static void qcow_close(BlockDriverState *bs)
 error_free(s->migration_blocker);
 }
 
-static int qcow_create(const char *filename, QEMUOptionParameter *options,
-   Error **errp)
+static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 int header_size, backing_filename_len, l1_size, shift, i;
 QCowHeader header;
 uint8_t *tmp;
 int64_t total_size = 0;
-const char *backing_file = NULL;
+char *backing_file = NULL;
 int flags = 0;
 Error *local_err = NULL;
 int ret;
 BlockDriverState *qcow_bs;
 
 /* Read out options */
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-total_size = options->value.n / 512;
-} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-backing_file = options->value.s;
-} else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
-flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
-}
-options++;
+total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
+backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
+if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
+flags |= BLOCK_FLAG_ENCRYPT;
 }
 
-ret = bdrv_create_file(filename, options, NULL, &local_err);
+ret = bdrv_create_file(filename, NULL, opts, &local_err);
 if (ret < 0) {
 error_propagate(errp, local_err);
-return ret;
+goto cleanup;
 }
 
 qcow_bs = NULL;
@@ -698,7 +692,7 @@ static int qcow_create(const char *filename, 
QEMUOptionParameter *options,
 BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
 if (ret < 0) {
 error_propagate(errp, local_err);
-return ret;
+goto cleanup;
 }
 
 ret = bdrv_truncate(qcow_bs, 0);
@@ -769,6 +763,8 @@ static int qcow_create(const char *filename, 
QEMUOptionParameter *options,
 ret = 0;
 exit:
 bdrv_unref(qcow_bs);
+cleanup:
+g_free(backing_file);
 return ret;
 }
 
@@ -881,24 +877,28 @@ static int qcow_get_info(BlockDriverState *bs, 
BlockDriverInfo *bdi)
 return 0;
 }
 
-
-static QEMUOptionParameter qcow_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size"
-},
-{
-.name = BLOCK_OPT_BACKING_FILE,
-.type = OPT_STRING,
-.help = "File name of a base image"
-},
-{
-.name = BLOCK_OPT_ENCRYPT,
-.type = OPT_FLAG,
-.help = "Encrypt the image"
-},
-{ NULL }
+static QemuOptsList qcow_create_opts = {
+.name = "qcow-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(qcow_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+},
+{
+.name = BLOCK_OPT_BACKING_FILE,
+.type = QEMU_OPT_STRING,
+.help = "File name of a base image"
+},
+{
+.name = BLOCK_OPT_ENCRYPT,
+.type = QEMU_OPT_BOOL,
+.help = "Encrypt the image",
+.def_value_str = "off"
+},
+{ /* end of list */ }
+}
 };
 
 static BlockDriver bdrv_qcow = {
@@ -907,8 +907,8 @@ static BlockDriver bdrv_qcow = {
 .bdrv_probe= qcow_probe,
 .bdrv_open = qcow_open,
 .bdrv_close= qcow_close,
-.bdrv_reopen_prepare = qcow_reopen_prepare,
-.bdrv_create   = qcow_create,
+.bdrv_reopen_prepare= qcow_reopen_prepare,
+.bdrv_create2   = qcow_create,
 .bdrv_has_zero_init = bdrv_has_zero_init_1,
 
 .bdrv_co_readv  = qcow_co_readv,
@@ -920,7 +920,7 @@ static BlockDriver bdrv_qcow = {
 .bdrv_write_compressed  = qcow_write_compressed,
 .bdrv_get_info  = qcow_get_info,
 
-.create_options = qcow_create_options,
+.create_opts= &qcow_create_opts,
 };
 
 static void bdrv_qcow_init(void)
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 14/31] gluster.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Eric Blake 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/gluster.c | 81 ++---
 1 file changed, 42 insertions(+), 39 deletions(-)

diff --git a/block/gluster.c b/block/gluster.c
index 8836085..9f44428 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -471,13 +471,14 @@ static inline int qemu_gluster_zerofill(struct glfs_fd 
*fd, int64_t offset,
 #endif
 
 static int qemu_gluster_create(const char *filename,
-QEMUOptionParameter *options, Error **errp)
+   QemuOpts *opts, Error **errp)
 {
 struct glfs *glfs;
 struct glfs_fd *fd;
 int ret = 0;
 int prealloc = 0;
 int64_t total_size = 0;
+char *tmp = NULL;
 GlusterConf *gconf = g_malloc0(sizeof(GlusterConf));
 
 glfs = qemu_gluster_init(gconf, filename, errp);
@@ -486,24 +487,21 @@ static int qemu_gluster_create(const char *filename,
 goto out;
 }
 
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-total_size = options->value.n / BDRV_SECTOR_SIZE;
-} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
-if (!options->value.s || !strcmp(options->value.s, "off")) {
-prealloc = 0;
-} else if (!strcmp(options->value.s, "full") &&
-gluster_supports_zerofill()) {
-prealloc = 1;
-} else {
-error_setg(errp, "Invalid preallocation mode: '%s'"
-" or GlusterFS doesn't support zerofill API",
-   options->value.s);
-ret = -EINVAL;
-goto out;
-}
-}
-options++;
+total_size =
+qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
+
+tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
+if (!tmp || !strcmp(tmp, "off")) {
+prealloc = 0;
+} else if (!strcmp(tmp, "full") &&
+   gluster_supports_zerofill()) {
+prealloc = 1;
+} else {
+error_setg(errp, "Invalid preallocation mode: '%s'"
+" or GlusterFS doesn't support zerofill API",
+tmp);
+ret = -EINVAL;
+goto out;
 }
 
 fd = glfs_creat(glfs, gconf->image,
@@ -525,6 +523,7 @@ static int qemu_gluster_create(const char *filename,
 }
 }
 out:
+g_free(tmp);
 qemu_gluster_gconf_free(gconf);
 if (glfs) {
 glfs_fini(glfs);
@@ -688,18 +687,22 @@ static int qemu_gluster_has_zero_init(BlockDriverState 
*bs)
 return 0;
 }
 
-static QEMUOptionParameter qemu_gluster_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size"
-},
-{
-.name = BLOCK_OPT_PREALLOC,
-.type = OPT_STRING,
-.help = "Preallocation mode (allowed values: off, full)"
-},
-{ NULL }
+static QemuOptsList qemu_gluster_create_opts = {
+.name = "qemu-gluster-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(qemu_gluster_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+},
+{
+.name = BLOCK_OPT_PREALLOC,
+.type = OPT_STRING,
+.help = "Preallocation mode (allowed values: off, full)"
+},
+{ /* end of list */ }
+}
 };
 
 static BlockDriver bdrv_gluster = {
@@ -712,7 +715,7 @@ static BlockDriver bdrv_gluster = {
 .bdrv_reopen_commit   = qemu_gluster_reopen_commit,
 .bdrv_reopen_abort= qemu_gluster_reopen_abort,
 .bdrv_close   = qemu_gluster_close,
-.bdrv_create  = qemu_gluster_create,
+.bdrv_create2 = qemu_gluster_create,
 .bdrv_getlength   = qemu_gluster_getlength,
 .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
 .bdrv_truncate= qemu_gluster_truncate,
@@ -726,7 +729,7 @@ static BlockDriver bdrv_gluster = {
 #ifdef CONFIG_GLUSTERFS_ZEROFILL
 .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
 #endif
-.create_options   = qemu_gluster_create_options,
+.create_opts  = &qemu_gluster_create_opts,
 };
 
 static BlockDriver bdrv_gluster_tcp = {
@@ -739,7 +742,7 @@ static BlockDriver bdrv_gluster_tcp = {
 .bdrv_reopen_commit   = qemu_gluster_reopen_commit,
 .bdrv_reopen_abort= qemu_gluster_reopen_abort,
 .bdrv_close   = qemu_gluster_close,
-.bdrv_create  = qemu_gluster_create,
+.bdrv_create2 = qemu_gluster_create,
 .bdrv_getlength   = qemu_gluster_getlength,
 .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
 .bdrv_truncate= qemu_gluster_truncate

[Qemu-devel] [PATCH v25 22/31] raw_bsd.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/raw_bsd.c | 27 +++
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 9ae5fc2..ee797fd 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -29,13 +29,17 @@
 #include "block/block_int.h"
 #include "qemu/option.h"
 
-static QEMUOptionParameter raw_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size"
-},
-{ 0 }
+static QemuOptsList raw_create_opts = {
+.name = "raw-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+},
+{ /* end of list */ }
+}
 };
 
 static int raw_reopen_prepare(BDRVReopenState *reopen_state,
@@ -139,13 +143,12 @@ static int raw_has_zero_init(BlockDriverState *bs)
 return bdrv_has_zero_init(bs->file);
 }
 
-static int raw_create(const char *filename, QEMUOptionParameter *options,
-  Error **errp)
+static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 Error *local_err = NULL;
 int ret;
 
-ret = bdrv_create_file(filename, options, NULL, &local_err);
+ret = bdrv_create_file(filename, NULL, opts, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 }
@@ -177,7 +180,7 @@ static BlockDriver bdrv_raw = {
 .bdrv_reopen_prepare  = &raw_reopen_prepare,
 .bdrv_open= &raw_open,
 .bdrv_close   = &raw_close,
-.bdrv_create  = &raw_create,
+.bdrv_create2 = &raw_create,
 .bdrv_co_readv= &raw_co_readv,
 .bdrv_co_writev   = &raw_co_writev,
 .bdrv_co_write_zeroes = &raw_co_write_zeroes,
@@ -194,7 +197,7 @@ static BlockDriver bdrv_raw = {
 .bdrv_lock_medium = &raw_lock_medium,
 .bdrv_ioctl   = &raw_ioctl,
 .bdrv_aio_ioctl   = &raw_aio_ioctl,
-.create_options   = &raw_create_options[0],
+.create_opts  = &raw_create_opts,
 .bdrv_has_zero_init   = &raw_has_zero_init
 };
 
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 11/31] change block layer to support both QemuOpts and QEMUOptionParamter

2014-04-10 Thread Chunyan Liu
Change block layer to support both QemuOpts and QEMUOptionParameter.
After this patch, it will change backend drivers one by one. At the end,
QEMUOptionParameter will be removed and only QemuOpts is kept.

Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block.c   | 151 +++---
 block/cow.c   |   2 +-
 block/qcow.c  |   2 +-
 block/qcow2.c |   2 +-
 block/qed.c   |   2 +-
 block/raw_bsd.c   |   2 +-
 block/vhdx.c  |   2 +-
 block/vmdk.c  |   4 +-
 block/vvfat.c |   2 +-
 include/block/block.h |   7 ++-
 include/block/block_int.h |  11 +++-
 qemu-img.c|  94 ++---
 12 files changed, 170 insertions(+), 111 deletions(-)

diff --git a/block.c b/block.c
index 990a754..560cbd5 100644
--- a/block.c
+++ b/block.c
@@ -408,6 +408,7 @@ typedef struct CreateCo {
 BlockDriver *drv;
 char *filename;
 QEMUOptionParameter *options;
+QemuOpts *opts;
 int ret;
 Error *err;
 } CreateCo;
@@ -419,8 +420,27 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
 
 CreateCo *cco = opaque;
 assert(cco->drv);
-
-ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
+assert(!(cco->options && cco->opts));
+
+if (cco->drv->bdrv_create2) {
+QemuOptsList *opts_list = NULL;
+QemuOpts *opts = NULL;
+if (!cco->opts) {
+opts_list = params_to_opts(cco->options);
+cco->opts = opts =
+qemu_opts_create(opts_list, NULL, 0, &error_abort);
+}
+ret = cco->drv->bdrv_create2(cco->filename, cco->opts, &local_err);
+qemu_opts_del(opts);
+qemu_opts_free(opts_list);
+} else {
+QEMUOptionParameter *options = NULL;
+if (!cco->options) {
+cco->options = options = opts_to_params(cco->opts);
+}
+ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
+free_option_parameters(options);
+}
 if (local_err) {
 error_propagate(&cco->err, local_err);
 }
@@ -428,7 +448,8 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
 }
 
 int bdrv_create(BlockDriver *drv, const char* filename,
-QEMUOptionParameter *options, Error **errp)
+QEMUOptionParameter *options,
+QemuOpts *opts, Error **errp)
 {
 int ret;
 
@@ -437,11 +458,12 @@ int bdrv_create(BlockDriver *drv, const char* filename,
 .drv = drv,
 .filename = g_strdup(filename),
 .options = options,
+.opts = opts,
 .ret = NOT_DONE,
 .err = NULL,
 };
 
-if (!drv->bdrv_create) {
+if (!drv->bdrv_create && !drv->bdrv_create2) {
 error_setg(errp, "Driver '%s' does not support image creation", 
drv->format_name);
 ret = -ENOTSUP;
 goto out;
@@ -473,7 +495,7 @@ out:
 }
 
 int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
- Error **errp)
+ QemuOpts *opts, Error **errp)
 {
 BlockDriver *drv;
 Error *local_err = NULL;
@@ -485,7 +507,7 @@ int bdrv_create_file(const char* filename, 
QEMUOptionParameter *options,
 return -ENOENT;
 }
 
-ret = bdrv_create(drv, filename, options, &local_err);
+ret = bdrv_create(drv, filename, options, opts, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 }
@@ -1174,7 +1196,8 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, 
Error **errp)
 
 int64_t total_size;
 BlockDriver *bdrv_qcow2;
-QEMUOptionParameter *create_options;
+QemuOptsList *create_opts = NULL;
+QemuOpts *opts = NULL;
 QDict *snapshot_options;
 BlockDriverState *bs_snapshot;
 Error *local_err;
@@ -1199,13 +1222,20 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, 
Error **errp)
 }
 
 bdrv_qcow2 = bdrv_find_format("qcow2");
-create_options = parse_option_parameters("", bdrv_qcow2->create_options,
- NULL);
 
-set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);
-
-ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err);
-free_option_parameters(create_options);
+assert(!(bdrv_qcow2->create_options && bdrv_qcow2->create_opts));
+if (bdrv_qcow2->create_options) {
+create_opts = params_to_opts(bdrv_qcow2->create_options);
+} else {
+create_opts = bdrv_qcow2->create_opts;
+}
+opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
+ret = bdrv_create(bdrv_qcow2, tmp_filename, NULL, opts, &local_err);
+qemu_opts_del(opts);
+if (bdrv_qcow2->create_options) {
+qemu_opts_free(create_opts);
+}
 if (ret < 0) {
 error_setg_errno(errp, -ret, "Could not create temporary overl

[Qemu-devel] [PATCH v25 15/31] iscsi.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/iscsi.c | 34 --
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/block/iscsi.c b/block/iscsi.c
index 64a509f..8544281 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1391,8 +1391,7 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t 
offset)
 return 0;
 }
 
-static int iscsi_create(const char *filename, QEMUOptionParameter *options,
-Error **errp)
+static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 int ret = 0;
 int64_t total_size = 0;
@@ -1403,13 +1402,8 @@ static int iscsi_create(const char *filename, 
QEMUOptionParameter *options,
 bs = bdrv_new("");
 
 /* Read out options */
-while (options && options->name) {
-if (!strcmp(options->name, "size")) {
-total_size = options->value.n / BDRV_SECTOR_SIZE;
-}
-options++;
-}
-
+total_size =
+qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
 bs->opaque = g_malloc0(sizeof(struct IscsiLun));
 iscsilun = bs->opaque;
 
@@ -1460,13 +1454,17 @@ static int iscsi_get_info(BlockDriverState *bs, 
BlockDriverInfo *bdi)
 return 0;
 }
 
-static QEMUOptionParameter iscsi_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size"
-},
-{ NULL }
+static QemuOptsList iscsi_create_opts = {
+.name = "iscsi-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(iscsi_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+},
+{ /* end of list */ }
+}
 };
 
 static BlockDriver bdrv_iscsi = {
@@ -1477,8 +1475,8 @@ static BlockDriver bdrv_iscsi = {
 .bdrv_needs_filename = true,
 .bdrv_file_open  = iscsi_open,
 .bdrv_close  = iscsi_close,
-.bdrv_create = iscsi_create,
-.create_options  = iscsi_create_options,
+.bdrv_create2= iscsi_create,
+.create_opts = &iscsi_create_opts,
 .bdrv_reopen_prepare  = iscsi_reopen_prepare,
 
 .bdrv_getlength  = iscsi_getlength,
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 10/31] QemuOpts: check NULL input for qemu_opts_del

2014-04-10 Thread Chunyan Liu
To simplify later using of qemu_opts_del, accept NULL input.

Reviewed-by: Eric Blake 
Signed-off-by: Chunyan Liu 
---
 util/qemu-option.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/util/qemu-option.c b/util/qemu-option.c
index d1e4d94..6222cd6 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -1010,6 +1010,10 @@ void qemu_opts_del(QemuOpts *opts)
 {
 QemuOpt *opt;
 
+if (opts == NULL) {
+return;
+}
+
 for (;;) {
 opt = QTAILQ_FIRST(&opts->head);
 if (opt == NULL)
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 07/31] QemuOpts: add qemu_opts_print_help to replace print_option_help

2014-04-10 Thread Chunyan Liu
print_option_help takes QEMUOptionParameter as parameter, add
qemu_opts_print_help to take QemuOptsList as parameter for later
replace work.

Reviewed-by: Leandro Dorileo 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 include/qemu/option.h |  1 +
 util/qemu-option.c| 13 +
 2 files changed, 14 insertions(+)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index 6653e43..fbf5dc2 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -166,5 +166,6 @@ typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void 
*opaque);
 void qemu_opts_print(QemuOpts *opts);
 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void 
*opaque,
   int abort_on_failure);
+void qemu_opts_print_help(QemuOptsList *list);
 
 #endif
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 70743a4..3c756f0 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -553,6 +553,19 @@ void print_option_help(QEMUOptionParameter *list)
 }
 }
 
+void qemu_opts_print_help(QemuOptsList *list)
+{
+QemuOptDesc *desc;
+
+assert(list);
+desc = list->desc;
+printf("Supported options:\n");
+while (desc && desc->name) {
+printf("%-16s %s\n", desc->name,
+   desc->help ? desc->help : "No description available");
+desc++;
+}
+}
 /* -- */
 
 static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 06/31] QemuOpts: add qemu_opt_get_*_del functions for replace work

2014-04-10 Thread Chunyan Liu
Add qemu_opt_get_del, qemu_opt_get_bool_del, qemu_opt_get_number_del and
qemu_opt_get_size_del to replace the same handling of QEMUOptionParamter
(get and delete).

Several drivers are coded to parse a known subset of options, then
remove them from the list before handing all remaining options to a
second driver for further option processing.  get_*_del makes it easier
to retrieve a known option (or its default) and remove it from the list
all in one action.

Share common helper function:

For qemu_opt_get_bool/size/number, they and their get_*_del counterpart
could share most of the code except whether or not deleting the opt from
option list, so generate common helper functions.

For qemu_opt_get and qemu_opt_get_del, keep code duplication, since
1. qemu_opt_get_del returns malloc'd memory while qemu_opt_get returns
in-place memory
2. qemu_opt_get_del returns (char *), qemu_opt_get returns (const char *),
and could not change to (char *), since in one case, it will return
desc->def_value_str, which is (const char *).

Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 include/qemu/option.h |   6 +++
 util/qemu-option.c| 116 --
 2 files changed, 109 insertions(+), 13 deletions(-)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index c3b0a91..6653e43 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -111,6 +111,7 @@ struct QemuOptsList {
 };
 
 const char *qemu_opt_get(QemuOpts *opts, const char *name);
+char *qemu_opt_get_del(QemuOpts *opts, const char *name);
 /**
  * qemu_opt_has_help_opt:
  * @opts: options to search for a help request
@@ -126,6 +127,11 @@ bool qemu_opt_has_help_opt(QemuOpts *opts);
 bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval);
 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t 
defval);
 uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval);
+bool qemu_opt_get_bool_del(QemuOpts *opts, const char *name, bool defval);
+uint64_t qemu_opt_get_number_del(QemuOpts *opts, const char *name,
+ uint64_t defval);
+uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name,
+   uint64_t defval);
 int qemu_opt_unset(QemuOpts *opts, const char *name);
 int qemu_opt_set(QemuOpts *opts, const char *name, const char *value);
 void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 9f59c07..70743a4 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -575,6 +575,19 @@ static void qemu_opt_del(QemuOpt *opt)
 g_free(opt);
 }
 
+/* qemu_opt_set allow many settings for the same option.
+ * This function is to delete all settings for an option.
+ */
+static void qemu_opt_del_all(QemuOpts *opts, const char *name)
+{
+QemuOpt *opt, *next_opt;
+
+QTAILQ_FOREACH_SAFE(opt, &opts->head, next, next_opt) {
+if (!strcmp(opt->name, name))
+qemu_opt_del(opt);
+}
+}
+
 const char *qemu_opt_get(QemuOpts *opts, const char *name)
 {
 QemuOpt *opt = qemu_opt_find(opts, name);
@@ -588,6 +601,34 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name)
 return opt ? opt->str : NULL;
 }
 
+/* Get a known option (or its default) and remove it from the list
+ * all in one action. Return a malloced string of the option vaule.
+ * Result must be freed by caller with g_free().
+ */
+char *qemu_opt_get_del(QemuOpts *opts, const char *name)
+{
+QemuOpt *opt;
+const QemuOptDesc *desc;
+char *str = NULL;
+
+if (opts == NULL) {
+return NULL;
+}
+
+opt = qemu_opt_find(opts, name);
+if (!opt) {
+desc = find_desc_by_name(opts->list->desc, name);
+if (desc && desc->def_value_str) {
+str = g_strdup(desc->def_value_str);
+}
+return str;
+}
+str = opt->str;
+opt->str = NULL;
+qemu_opt_del_all(opts, name);
+return str;
+}
+
 bool qemu_opt_has_help_opt(QemuOpts *opts)
 {
 QemuOpt *opt;
@@ -600,50 +641,99 @@ bool qemu_opt_has_help_opt(QemuOpts *opts)
 return false;
 }
 
-bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
+static bool qemu_opt_get_bool_helper(QemuOpts *opts, const char *name,
+ bool defval, bool del)
 {
 QemuOpt *opt = qemu_opt_find(opts, name);
+bool ret = defval;
 
 if (opt == NULL) {
 const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
 if (desc && desc->def_value_str) {
-parse_option_bool(name, desc->def_value_str, &defval, 
&error_abort);
+parse_option_bool(name, desc->def_value_str, &ret, &error_abort);
 }
-return defval;
+return ret;
 }
 assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
-return opt->value.boolean;
+ret = opt->value.boolean;
+if (del) {
+qemu_opt_del_all(opts, name);
+ 

[Qemu-devel] [PATCH v25 13/31] cow.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Eric Blake 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/cow.c | 54 ++
 1 file changed, 26 insertions(+), 28 deletions(-)

diff --git a/block/cow.c b/block/cow.c
index 26cf4a5..fb2cd68 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -324,31 +324,24 @@ static void cow_close(BlockDriverState *bs)
 {
 }
 
-static int cow_create(const char *filename, QEMUOptionParameter *options,
-  Error **errp)
+static int cow_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 struct cow_header_v2 cow_header;
 struct stat st;
 int64_t image_sectors = 0;
-const char *image_filename = NULL;
+char *image_filename = NULL;
 Error *local_err = NULL;
 int ret;
 BlockDriverState *cow_bs;
 
 /* Read out options */
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-image_sectors = options->value.n / 512;
-} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
-image_filename = options->value.s;
-}
-options++;
-}
+image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
+image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 
-ret = bdrv_create_file(filename, options, NULL, &local_err);
+ret = bdrv_create_file(filename, NULL, opts, &local_err);
 if (ret < 0) {
 error_propagate(errp, local_err);
-return ret;
+goto exit;
 }
 
 cow_bs = NULL;
@@ -356,7 +349,7 @@ static int cow_create(const char *filename, 
QEMUOptionParameter *options,
 BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
 if (ret < 0) {
 error_propagate(errp, local_err);
-return ret;
+goto exit;
 }
 
 memset(&cow_header, 0, sizeof(cow_header));
@@ -389,22 +382,27 @@ static int cow_create(const char *filename, 
QEMUOptionParameter *options,
 }
 
 exit:
+g_free(image_filename);
 bdrv_unref(cow_bs);
 return ret;
 }
 
-static QEMUOptionParameter cow_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size"
-},
-{
-.name = BLOCK_OPT_BACKING_FILE,
-.type = OPT_STRING,
-.help = "File name of a base image"
-},
-{ NULL }
+static QemuOptsList cow_create_opts = {
+.name = "cow-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(cow_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+},
+{
+.name = BLOCK_OPT_BACKING_FILE,
+.type = QEMU_OPT_STRING,
+.help = "File name of a base image"
+},
+{ /* end of list */ }
+}
 };
 
 static BlockDriver bdrv_cow = {
@@ -414,14 +412,14 @@ static BlockDriver bdrv_cow = {
 .bdrv_probe = cow_probe,
 .bdrv_open  = cow_open,
 .bdrv_close = cow_close,
-.bdrv_create= cow_create,
+.bdrv_create2   = cow_create,
 .bdrv_has_zero_init = bdrv_has_zero_init_1,
 
 .bdrv_read  = cow_co_read,
 .bdrv_write = cow_co_write,
 .bdrv_co_get_block_status   = cow_co_get_block_status,
 
-.create_options = cow_create_options,
+.create_opts= &cow_create_opts,
 };
 
 static void bdrv_cow_init(void)
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 20/31] raw-posix.c: replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
 block/raw-posix.c | 59 +--
 1 file changed, 27 insertions(+), 32 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 1688e16..e72f449 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1234,8 +1234,7 @@ static int64_t 
raw_get_allocated_file_size(BlockDriverState *bs)
 return (int64_t)st.st_blocks * 512;
 }
 
-static int raw_create(const char *filename, QEMUOptionParameter *options,
-  Error **errp)
+static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
 {
 int fd;
 int result = 0;
@@ -1244,12 +1243,8 @@ static int raw_create(const char *filename, 
QEMUOptionParameter *options,
 strstart(filename, "file:", &filename);
 
 /* Read out options */
-while (options && options->name) {
-if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-total_size = options->value.n / BDRV_SECTOR_SIZE;
-}
-options++;
-}
+total_size =
+qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
 
 fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
@@ -1410,13 +1405,17 @@ static int raw_get_info(BlockDriverState *bs, 
BlockDriverInfo *bdi)
 return 0;
 }
 
-static QEMUOptionParameter raw_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = "Virtual disk size"
-},
-{ NULL }
+static QemuOptsList raw_create_opts = {
+.name = "raw-create-opts",
+.head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
+.desc = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Virtual disk size"
+},
+{ /* end of list */ }
+}
 };
 
 static BlockDriver bdrv_file = {
@@ -1431,7 +1430,7 @@ static BlockDriver bdrv_file = {
 .bdrv_reopen_commit = raw_reopen_commit,
 .bdrv_reopen_abort = raw_reopen_abort,
 .bdrv_close = raw_close,
-.bdrv_create = raw_create,
+.bdrv_create2 = raw_create,
 .bdrv_has_zero_init = bdrv_has_zero_init_1,
 .bdrv_co_get_block_status = raw_co_get_block_status,
 .bdrv_co_write_zeroes = raw_co_write_zeroes,
@@ -1448,7 +1447,7 @@ static BlockDriver bdrv_file = {
 .bdrv_get_allocated_file_size
 = raw_get_allocated_file_size,
 
-.create_options = raw_create_options,
+.create_opts = &raw_create_opts,
 };
 
 /***/
@@ -1769,7 +1768,7 @@ static coroutine_fn int 
hdev_co_write_zeroes(BlockDriverState *bs,
 return -ENOTSUP;
 }
 
-static int hdev_create(const char *filename, QEMUOptionParameter *options,
+static int hdev_create(const char *filename, QemuOpts *opts,
Error **errp)
 {
 int fd;
@@ -1790,12 +1789,8 @@ static int hdev_create(const char *filename, 
QEMUOptionParameter *options,
 (void)has_prefix;
 
 /* Read out options */
-while (options && options->name) {
-if (!strcmp(options->name, "size")) {
-total_size = options->value.n / BDRV_SECTOR_SIZE;
-}
-options++;
-}
+total_size =
+qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
 
 fd = qemu_open(filename, O_WRONLY | O_BINARY);
 if (fd < 0) {
@@ -1832,8 +1827,8 @@ static BlockDriver bdrv_host_device = {
 .bdrv_reopen_prepare = raw_reopen_prepare,
 .bdrv_reopen_commit  = raw_reopen_commit,
 .bdrv_reopen_abort   = raw_reopen_abort,
-.bdrv_create= hdev_create,
-.create_options = raw_create_options,
+.bdrv_create2= hdev_create,
+.create_opts = &raw_create_opts,
 .bdrv_co_write_zeroes = hdev_co_write_zeroes,
 
 .bdrv_aio_readv= raw_aio_readv,
@@ -1976,8 +1971,8 @@ static BlockDriver bdrv_host_floppy = {
 .bdrv_reopen_prepare = raw_reopen_prepare,
 .bdrv_reopen_commit  = raw_reopen_commit,
 .bdrv_reopen_abort   = raw_reopen_abort,
-.bdrv_create= hdev_create,
-.create_options = raw_create_options,
+.bdrv_create2= hdev_create,
+.create_opts = &raw_create_opts,
 
 .bdrv_aio_readv = raw_aio_readv,
 .bdrv_aio_writev= raw_aio_writev,
@@ -2101,8 +2096,8 @@ static BlockDriver bdrv_host_cdrom = {
 .bdrv_reopen_prepare = raw_reopen_prepare,
 .bdrv_reopen_commit  = raw_reopen_commit,
 .bdrv_reopen_abort   = raw_reopen_abort,
-.bdrv_create= hdev_create,
-.create_options = raw_create_options,
+.bdrv_create2= hdev_create,
+.create_opts = &raw_create_opts,
 
 .bdrv_aio_readv = raw_aio_readv,
 .bdrv_aio_writev= raw_aio_writev,
@@ -2232,8 +2227,8 @@ static BlockDriver bdrv_host_cdrom = {
 .bdrv_reopen_prepare = raw_reopen_prepare,
 .bdrv_reopen_commit  = raw_reopen_commit,
 .bdrv_reopen_

[Qemu-devel] [PATCH v25 00/31] replace QEMUOptionParameter with QemuOpts

2014-04-10 Thread Chunyan Liu
This patch series is to replace QEMUOptionParameter with QemuOpts, so that only
one Qemu Option structure is kept in QEMU code.

---
Changes to v24:
  * fix Leandro's comments to v23
  * add patch for block/nfs.c
  * rebase to latest code

All patches are also available from:
https://github.com/chunyanliu/qemu/commits/QemuOpts

Chunyan Liu (31):
  QemuOpts: move find_desc_by_name ahead for later calling
  QemuOpts: add def_value_str to QemuOptDesc
  qapi: output def_value_str when query command line options
  QemuOpts: change opt->name|str from (const char *) to (char *)
  QemuOpts: move qemu_opt_del ahead for later calling
  QemuOpts: add qemu_opt_get_*_del functions for replace work
  QemuOpts: add qemu_opts_print_help to replace print_option_help
  QemuOpts: add conversion between QEMUOptionParameter to QemuOpts
  QemuOpts: add qemu_opts_append to replace append_option_parameters
  QemuOpts: check NULL input for qemu_opts_del
  change block layer to support both QemuOpts and QEMUOptionParamter
  vvfat.c: handle cross_driver's create_options and create_opts
  cow.c: replace QEMUOptionParameter with QemuOpts
  gluster.c: replace QEMUOptionParameter with QemuOpts
  iscsi.c: replace QEMUOptionParameter with QemuOpts
  nfs.c: replace QEMUOptionParameter with QemuOpts
  qcow.c: replace QEMUOptionParameter with QemuOpts
  qcow2.c: replace QEMUOptionParameter with QemuOpts
  qed.c: replace QEMUOptionParameter with QemuOpts
  raw-posix.c: replace QEMUOptionParameter with QemuOpts
  raw-win32.c: replace QEMUOptionParameter with QemuOpts
  raw_bsd.c: replace QEMUOptionParameter with QemuOpts
  rbd.c: replace QEMUOptionParameter with QemuOpts
  sheepdog.c: replace QEMUOptionParameter with QemuOpts
  ssh.c: replace QEMUOptionParameter with QemuOpts
  vdi.c: replace QEMUOptionParameter with QemuOpts
  vhdx.c: replace QEMUOptionParameter with QemuOpts
  vmdk.c: replace QEMUOptionParameter with QemuOpts
  vpc.c: replace QEMUOptionParameter with QemuOpts
  cleanup QEMUOptionParameter
  QemuOpts: cleanup tmp 'allocated' member from QemuOptsList

 block.c   |  97 
 block/cow.c   |  52 ++--
 block/gluster.c   |  73 +++---
 block/iscsi.c |  32 ++-
 block/nfs.c   |  10 +-
 block/qcow.c  |  72 +++---
 block/qcow2.c | 265 +++--
 block/qed.c   | 112 -
 block/qed.h   |   3 +-
 block/raw-posix.c |  55 ++---
 block/raw-win32.c |  38 +--
 block/raw_bsd.c   |  25 +-
 block/rbd.c   |  61 +++--
 block/sheepdog.c  | 102 
 block/ssh.c   |  30 ++-
 block/vdi.c   |  71 +++---
 block/vhdx.c  |  97 
 block/vhdx.h  |   1 +
 block/vmdk.c  | 121 +-
 block/vpc.c   |  60 ++---
 block/vvfat.c |  11 +-
 include/block/block.h |   7 +-
 include/block/block_int.h |   9 +-
 include/qemu/option.h |  53 +
 include/qemu/option_int.h |   4 +-
 qapi-schema.json  |   6 +-
 qapi/opts-visitor.c   |  10 +-
 qemu-img.c|  89 ---
 qmp-commands.hx   |   2 +
 util/qemu-config.c|   4 +
 util/qemu-option.c| 587 --
 31 files changed, 1032 insertions(+), 1127 deletions(-)

-- 
1.7.12.4




[Qemu-devel] [PATCH v25 03/31] qapi: output def_value_str when query command line options

2014-04-10 Thread Chunyan Liu
Change qapi interfaces to output the newly added def_value_str when querying
command line options.

Reviewed-by: Eric Blake 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
changes:
  * Following Leandro's comment:
update description of @default

 qapi-schema.json   | 6 +-
 qmp-commands.hx| 2 ++
 util/qemu-config.c | 4 
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index 391356f..cc7c8b6 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4088,12 +4088,16 @@
 #
 # @help: #optional human readable text string, not suitable for parsing.
 #
+# @default: #optional option's default value - set if option is not
+#   informed. (since 2.1)
+#
 # Since 1.5
 ##
 { 'type': 'CommandLineParameterInfo',
   'data': { 'name': 'str',
 'type': 'CommandLineParameterType',
-'*help': 'str' } }
+'*help': 'str',
+'*default': 'str' } }
 
 ##
 # @CommandLineOptionInfo:
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ed3ab92..1271332 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2895,6 +2895,8 @@ Each array entry contains the following:
   or 'size')
 - "help": human readable description of the parameter
   (json-string, optional)
+- "default": default value string for the parameter
+ (json-string, optional)
 
 Example:
 
diff --git a/util/qemu-config.c b/util/qemu-config.c
index f610101..d608b2f 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -68,6 +68,10 @@ static CommandLineParameterInfoList 
*query_option_descs(const QemuOptDesc *desc)
 info->has_help = true;
 info->help = g_strdup(desc[i].help);
 }
+if (desc[i].def_value_str) {
+info->has_q_default = true;
+info->q_default = g_strdup(desc[i].def_value_str);
+}
 
 entry = g_malloc0(sizeof(*entry));
 entry->value = info;
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 08/31] QemuOpts: add conversion between QEMUOptionParameter to QemuOpts

2014-04-10 Thread Chunyan Liu
Add two temp conversion functions between QEMUOptionParameter to QemuOpts,
so that next patch can use it. It will simplify later patch for easier
review. And will be finally removed after all backend drivers switch to
QemuOpts.

Signed-off-by: Chunyan Liu 
---
 include/qemu/option.h |   8 +++
 util/qemu-option.c| 153 ++
 2 files changed, 161 insertions(+)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index fbf5dc2..4e637b5 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -103,6 +103,11 @@ typedef struct QemuOptDesc {
 } QemuOptDesc;
 
 struct QemuOptsList {
+/* FIXME: Temp used for QEMUOptionParamter->QemuOpts conversion to
+ * indicate free memory. Will remove after all drivers switch to QemuOpts.
+ */
+bool allocated;
+
 const char *name;
 const char *implied_opt_name;
 bool merge_lists;  /* Merge multiple uses of option into a single list? */
@@ -167,5 +172,8 @@ void qemu_opts_print(QemuOpts *opts);
 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void 
*opaque,
   int abort_on_failure);
 void qemu_opts_print_help(QemuOptsList *list);
+void qemu_opts_free(QemuOptsList *list);
+QEMUOptionParameter *opts_to_params(QemuOpts *opts);
+QemuOptsList *params_to_opts(QEMUOptionParameter *list);
 
 #endif
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 3c756f0..d658505 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -1345,3 +1345,156 @@ int qemu_opts_foreach(QemuOptsList *list, 
qemu_opts_loopfunc func, void *opaque,
 loc_pop(&loc);
 return rc;
 }
+
+static size_t count_opts_list(QemuOptsList *list)
+{
+QemuOptDesc *desc = NULL;
+size_t num_opts = 0;
+
+if (!list) {
+return 0;
+}
+
+desc = list->desc;
+while (desc && desc->name) {
+num_opts++;
+desc++;
+}
+
+return num_opts;
+}
+
+/* Convert QEMUOptionParameter to QemuOpts
+ * FIXME: this function will be removed after all drivers
+ * switch to QemuOpts
+ */
+QemuOptsList *params_to_opts(QEMUOptionParameter *list)
+{
+QemuOptsList *opts = NULL;
+size_t num_opts, i = 0;
+
+if (!list) {
+return NULL;
+}
+
+num_opts = count_option_parameters(list);
+opts = g_malloc0(sizeof(QemuOptsList) +
+ (num_opts + 1) * sizeof(QemuOptDesc));
+QTAILQ_INIT(&opts->head);
+/* (const char *) members will point to malloced space and need to free */
+opts->allocated = true;
+
+while (list && list->name) {
+opts->desc[i].name = g_strdup(list->name);
+opts->desc[i].help = g_strdup(list->help);
+switch (list->type) {
+case OPT_FLAG:
+opts->desc[i].type = QEMU_OPT_BOOL;
+opts->desc[i].def_value_str =
+g_strdup(list->value.n ? "on" : "off");
+break;
+
+case OPT_NUMBER:
+opts->desc[i].type = QEMU_OPT_NUMBER;
+if (list->value.n) {
+opts->desc[i].def_value_str =
+g_strdup_printf("%" PRIu64, list->value.n);
+}
+break;
+
+case OPT_SIZE:
+opts->desc[i].type = QEMU_OPT_SIZE;
+if (list->value.n) {
+opts->desc[i].def_value_str =
+g_strdup_printf("%" PRIu64, list->value.n);
+}
+break;
+
+case OPT_STRING:
+opts->desc[i].type = QEMU_OPT_STRING;
+opts->desc[i].def_value_str = g_strdup(list->value.s);
+break;
+}
+
+i++;
+list++;
+}
+
+return opts;
+}
+
+/* convert QemuOpts to QEMUOptionParameter
+ * Note: result QEMUOptionParameter has shorter lifetime than
+ * input QemuOpts.
+ * FIXME: this function will be removed after all drivers
+ * switch to QemuOpts
+ */
+QEMUOptionParameter *opts_to_params(QemuOpts *opts)
+{
+QEMUOptionParameter *dest = NULL;
+QemuOptDesc *desc;
+size_t num_opts, i = 0;
+const char *tmp;
+
+if (!opts || !opts->list || !opts->list->desc) {
+return NULL;
+}
+assert(!opts_accepts_any(opts));
+
+num_opts = count_opts_list(opts->list);
+dest = g_malloc0((num_opts + 1) * sizeof(QEMUOptionParameter));
+
+desc = opts->list->desc;
+while (desc && desc->name) {
+dest[i].name = desc->name;
+dest[i].help = desc->help;
+dest[i].assigned = qemu_opt_find(opts, desc->name) ? true : false;
+switch (desc->type) {
+case QEMU_OPT_STRING:
+dest[i].type = OPT_STRING;
+tmp = qemu_opt_get(opts, desc->name);
+dest[i].value.s = g_strdup(tmp);
+break;
+
+case QEMU_OPT_BOOL:
+dest[i].type = OPT_FLAG;
+dest[i].value.n = qemu_opt_get_bool(opts, desc->name, 0) ? 1 : 0;
+break;
+
+case QEMU_OPT_NUMBER:
+dest[i].type = OPT_NUMBER;
+dest[i].value.n = qemu_opt_get_

[Qemu-devel] [PATCH v25 09/31] QemuOpts: add qemu_opts_append to replace append_option_parameters

2014-04-10 Thread Chunyan Liu
For later merge .create_opts of drv and proto_drv in qemu-img commands.

Reviewed-by: Leandro Dorileo 
Signed-off-by: Chunyan Liu 
---
 include/qemu/option.h |  5 
 util/qemu-option.c| 65 +++
 2 files changed, 70 insertions(+)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index 4e637b5..88c4733 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -175,5 +175,10 @@ void qemu_opts_print_help(QemuOptsList *list);
 void qemu_opts_free(QemuOptsList *list);
 QEMUOptionParameter *opts_to_params(QemuOpts *opts);
 QemuOptsList *params_to_opts(QEMUOptionParameter *list);
+/* FIXME: will remove QEMUOptionParameter after all drivers switch to QemuOpts.
+ */
+QemuOptsList *qemu_opts_append(QemuOptsList *dst,
+   QemuOptsList *list,
+   QEMUOptionParameter *param);
 
 #endif
diff --git a/util/qemu-option.c b/util/qemu-option.c
index d658505..d1e4d94 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -1498,3 +1498,68 @@ void qemu_opts_free(QemuOptsList *list)
 
 g_free(list);
 }
+
+/* Realloc dst option list and append options either from an option list (list)
+ * or a QEMUOptionParameter (param) to it. dst could be NULL or a malloced 
list.
+ * FIXME: will remove QEMUOptionParameter after all drivers switch to QemuOpts.
+ */
+QemuOptsList *qemu_opts_append(QemuOptsList *dst,
+   QemuOptsList *list,
+   QEMUOptionParameter *param)
+{
+size_t num_opts, num_dst_opts;
+QemuOptsList *tmp_list = NULL;
+QemuOptDesc *desc;
+bool need_init = false;
+
+assert(!(list && param));
+if (!param && !list) {
+return dst;
+}
+
+if (param) {
+list = tmp_list = params_to_opts(param);
+}
+
+/* If dst is NULL, after realloc, some area of dst should be initialized
+ * before adding options to it.
+ */
+if (!dst) {
+need_init = true;
+}
+
+num_opts = count_opts_list(dst);
+num_dst_opts = num_opts;
+num_opts += count_opts_list(list);
+dst = g_realloc(dst, sizeof(QemuOptsList) +
+(num_opts + 1) * sizeof(QemuOptDesc));
+if (need_init) {
+dst->name = NULL;
+dst->implied_opt_name = NULL;
+QTAILQ_INIT(&dst->head);
+dst->allocated = true;
+}
+dst->desc[num_dst_opts].name = NULL;
+
+/* (const char *) members of result dst are malloced, need free. */
+assert(dst->allocated);
+/* append list->desc to dst->desc */
+if (list) {
+desc = list->desc;
+while (desc && desc->name) {
+if (find_desc_by_name(dst->desc, desc->name) == NULL) {
+dst->desc[num_dst_opts].name = g_strdup(desc->name);
+dst->desc[num_dst_opts].type = desc->type;
+dst->desc[num_dst_opts].help = g_strdup(desc->help);
+dst->desc[num_dst_opts].def_value_str =
+ g_strdup(desc->def_value_str);
+num_dst_opts++;
+dst->desc[num_dst_opts].name = NULL;
+}
+desc++;
+}
+}
+
+g_free(tmp_list);
+return dst;
+}
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 05/31] QemuOpts: move qemu_opt_del ahead for later calling

2014-04-10 Thread Chunyan Liu
In later patch, qemu_opt_get_del functions will be added, they will
first get the option value, then call qemu_opt_del to remove the option
from opt list. To prepare for that purpose, move qemu_opt_del ahead first.

Reviewed-by: Leandro Dorileo 
Reviewed-by: Eric Blake 
Signed-off-by: Chunyan Liu 
---
 util/qemu-option.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/util/qemu-option.c b/util/qemu-option.c
index 065ffb8..9f59c07 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -567,6 +567,14 @@ static QemuOpt *qemu_opt_find(QemuOpts *opts, const char 
*name)
 return NULL;
 }
 
+static void qemu_opt_del(QemuOpt *opt)
+{
+QTAILQ_REMOVE(&opt->opts->head, opt, next);
+g_free(opt->name);
+g_free(opt->str);
+g_free(opt);
+}
+
 const char *qemu_opt_get(QemuOpts *opts, const char *name)
 {
 QemuOpt *opt = qemu_opt_find(opts, name);
@@ -661,14 +669,6 @@ static void qemu_opt_parse(QemuOpt *opt, Error **errp)
 }
 }
 
-static void qemu_opt_del(QemuOpt *opt)
-{
-QTAILQ_REMOVE(&opt->opts->head, opt, next);
-g_free(opt->name);
-g_free(opt->str);
-g_free(opt);
-}
-
 static bool opts_accepts_any(const QemuOpts *opts)
 {
 return opts->list->desc[0].name == NULL;
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 01/31] QemuOpts: move find_desc_by_name ahead for later calling

2014-04-10 Thread Chunyan Liu
Reviewed-by: Leandro Dorileo 
Reviewed-by: Eric Blake 
Signed-off-by: Chunyan Liu 
---
 util/qemu-option.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/util/qemu-option.c b/util/qemu-option.c
index 9d898af..e6d10bc 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -173,6 +173,20 @@ static void parse_option_number(const char *name, const 
char *value,
 }
 }
 
+static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc,
+const char *name)
+{
+int i;
+
+for (i = 0; desc[i].name != NULL; i++) {
+if (strcmp(desc[i].name, name) == 0) {
+return &desc[i];
+}
+}
+
+return NULL;
+}
+
 void parse_option_size(const char *name, const char *value,
uint64_t *ret, Error **errp)
 {
@@ -637,20 +651,6 @@ static bool opts_accepts_any(const QemuOpts *opts)
 return opts->list->desc[0].name == NULL;
 }
 
-static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc,
-const char *name)
-{
-int i;
-
-for (i = 0; desc[i].name != NULL; i++) {
-if (strcmp(desc[i].name, name) == 0) {
-return &desc[i];
-}
-}
-
-return NULL;
-}
-
 int qemu_opt_unset(QemuOpts *opts, const char *name)
 {
 QemuOpt *opt = qemu_opt_find(opts, name);
-- 
1.7.12.4




[Qemu-devel] [PATCH v25 02/31] QemuOpts: add def_value_str to QemuOptDesc

2014-04-10 Thread Chunyan Liu
Add def_value_str (default value) to QemuOptDesc, to replace function of the
default value in QEMUOptionParameter.

Improve qemu_opts_get_* functions: if find opt, return opt->str; otherwise,
if desc->def_value_str is set, return desc->def_value_str; otherwise, return
input defval.

Improve qemu_opts_print: if option is set, print opt->str; otherwise, if
desc->def_value_str is set, also print it. It will replace
print_option_parameters. To avoid print info changes, change qemu_opts_print
from fprintf stderr to printf, and remove last printf.

Reviewed-by: Leandro Dorileo 
Reviewed-by: Eric Blake 
Signed-off-by: Dong Xu Wang 
Signed-off-by: Chunyan Liu 
---
changes:
  * Following Leandro's comment:
merge v24 0002-QemuOpts-add-def_value_str-to-QemuOptDesc.patch and
v24 0011-qemu_opts_print-change-fprintf-stderr-to-printf.patch into one.

 include/qemu/option.h |  3 ++-
 util/qemu-option.c| 60 ++-
 2 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index 8c0ac34..c3b0a91 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -99,6 +99,7 @@ typedef struct QemuOptDesc {
 const char *name;
 enum QemuOptType type;
 const char *help;
+const char *def_value_str;
 } QemuOptDesc;
 
 struct QemuOptsList {
@@ -156,7 +157,7 @@ QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
 void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
 
 typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
-int qemu_opts_print(QemuOpts *opts, void *dummy);
+void qemu_opts_print(QemuOpts *opts);
 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void 
*opaque,
   int abort_on_failure);
 
diff --git a/util/qemu-option.c b/util/qemu-option.c
index e6d10bc..84f0d5c 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -570,6 +570,13 @@ static QemuOpt *qemu_opt_find(QemuOpts *opts, const char 
*name)
 const char *qemu_opt_get(QemuOpts *opts, const char *name)
 {
 QemuOpt *opt = qemu_opt_find(opts, name);
+
+if (!opt) {
+const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
+if (desc && desc->def_value_str) {
+return desc->def_value_str;
+}
+}
 return opt ? opt->str : NULL;
 }
 
@@ -589,8 +596,13 @@ bool qemu_opt_get_bool(QemuOpts *opts, const char *name, 
bool defval)
 {
 QemuOpt *opt = qemu_opt_find(opts, name);
 
-if (opt == NULL)
+if (opt == NULL) {
+const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
+if (desc && desc->def_value_str) {
+parse_option_bool(name, desc->def_value_str, &defval, 
&error_abort);
+}
 return defval;
+}
 assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
 return opt->value.boolean;
 }
@@ -599,8 +611,14 @@ uint64_t qemu_opt_get_number(QemuOpts *opts, const char 
*name, uint64_t defval)
 {
 QemuOpt *opt = qemu_opt_find(opts, name);
 
-if (opt == NULL)
+if (opt == NULL) {
+const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
+if (desc && desc->def_value_str) {
+parse_option_number(name, desc->def_value_str, &defval,
+&error_abort);
+}
 return defval;
+}
 assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
 return opt->value.uint;
 }
@@ -609,8 +627,13 @@ uint64_t qemu_opt_get_size(QemuOpts *opts, const char 
*name, uint64_t defval)
 {
 QemuOpt *opt = qemu_opt_find(opts, name);
 
-if (opt == NULL)
+if (opt == NULL) {
+const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
+if (desc && desc->def_value_str) {
+parse_option_size(name, desc->def_value_str, &defval, 
&error_abort);
+}
 return defval;
+}
 assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
 return opt->value.uint;
 }
@@ -895,17 +918,34 @@ void qemu_opts_del(QemuOpts *opts)
 g_free(opts);
 }
 
-int qemu_opts_print(QemuOpts *opts, void *dummy)
+void qemu_opts_print(QemuOpts *opts)
 {
 QemuOpt *opt;
+QemuOptDesc *desc = opts->list->desc;
 
-fprintf(stderr, "%s: %s:", opts->list->name,
-opts->id ? opts->id : "");
-QTAILQ_FOREACH(opt, &opts->head, next) {
-fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
+if (desc[0].name == NULL) {
+QTAILQ_FOREACH(opt, &opts->head, next) {
+printf("%s=\"%s\" ", opt->name, opt->str);
+}
+return;
+}
+for (; desc && desc->name; desc++) {
+const char *value;
+QemuOpt *opt = qemu_opt_find(opts, desc->name);
+
+value = opt ? opt->str : desc->def_value_str;
+if (!value) {
+continue;
+}
+if (desc->type == QEMU_OPT_STRING) {
+printf("%s='%s' ", desc->name, value);
+} else if ((desc->type == QEMU_

[Qemu-devel] [PATCH v25 04/31] QemuOpts: change opt->name|str from (const char *) to (char *)

2014-04-10 Thread Chunyan Liu
qemu_opt_del() already assumes that all QemuOpt instances contain
malloc'd name and value; but it had to cast away const because
opts_start_struct() was doing its own thing and using static storage
instead.  By using the correct type and malloced strings everywhere, the
usage of this struct becomes clearer.

Reviewed-by: Leandro Dorileo 
Signed-off-by: Chunyan Liu 
---
 include/qemu/option_int.h |  4 ++--
 qapi/opts-visitor.c   | 10 +++---
 util/qemu-option.c|  4 ++--
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/include/qemu/option_int.h b/include/qemu/option_int.h
index 8212fa4..6432c1a 100644
--- a/include/qemu/option_int.h
+++ b/include/qemu/option_int.h
@@ -30,8 +30,8 @@
 #include "qemu/error-report.h"
 
 struct QemuOpt {
-const char   *name;
-const char   *str;
+char *name;
+char *str;
 
 const QemuOptDesc *desc;
 union {
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 5d830a2..7a64f4e 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -143,8 +143,8 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,
 if (ov->opts_root->id != NULL) {
 ov->fake_id_opt = g_malloc0(sizeof *ov->fake_id_opt);
 
-ov->fake_id_opt->name = "id";
-ov->fake_id_opt->str = ov->opts_root->id;
+ov->fake_id_opt->name = g_strdup("id");
+ov->fake_id_opt->str = g_strdup(ov->opts_root->id);
 opts_visitor_insert(ov->unprocessed_opts, ov->fake_id_opt);
 }
 }
@@ -177,7 +177,11 @@ opts_end_struct(Visitor *v, Error **errp)
 }
 g_hash_table_destroy(ov->unprocessed_opts);
 ov->unprocessed_opts = NULL;
-g_free(ov->fake_id_opt);
+if (ov->fake_id_opt) {
+g_free(ov->fake_id_opt->name);
+g_free(ov->fake_id_opt->str);
+g_free(ov->fake_id_opt);
+}
 ov->fake_id_opt = NULL;
 }
 
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 84f0d5c..065ffb8 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -664,8 +664,8 @@ static void qemu_opt_parse(QemuOpt *opt, Error **errp)
 static void qemu_opt_del(QemuOpt *opt)
 {
 QTAILQ_REMOVE(&opt->opts->head, opt, next);
-g_free((/* !const */ char*)opt->name);
-g_free((/* !const */ char*)opt->str);
+g_free(opt->name);
+g_free(opt->str);
 g_free(opt);
 }
 
-- 
1.7.12.4




Re: [Qemu-devel] [RFC v2 1/6] hw/arm/virt: add a xgmac device

2014-04-10 Thread Alistair Francis
On Thu, Apr 10, 2014 at 11:48 PM, Alexander Graf  wrote:
>
> On 10.04.14 15:26, Peter Crosthwaite wrote:
>>
>> On Thu, Apr 10, 2014 at 1:33 AM, Eric Auger  wrote:
>>>
>>> From: Kim Phillips 
>>>
>>> This is a hack and only serves as an example of what needs to be
>>> done to make the next RFC - add vfio-platform support - work
>>> for development purposes on a Calxeda Midway system.  We don't want
>>> mach-virt to always create this ethernet device - DO NOT APPLY, etc.
>>>
>>> Initial attempts to convince QEMU to create a memory mapped device
>>> on the command line (e.g., -device vfio-platform,name=fff51000.ethernet)
>>> would fail with "Parameter 'driver' expects pluggable device type".
>>
>> Alistair is working on this. cc.
>
>
> Alaistair, I've had patches tackle this on the mailing list a few months ago
> and received good comments from Anthony on what to change. How far in are
> you already? I'd like to make sure we're on the same page here (and don't
> duplicate work).
>
>
> Alex
>
>

Hey Alex,

I have a patch I'm about to send to the mailing list. It allows an
entire machine to be added by the -device argument on the command
line. It is a similar implementation to my first version (vl.c: Allow
sysbus devices to be attached via commandline), but much more generic.

Could you point me to your patches so I can compare? At the moment I
don't have much feedback to my implementation

Thanks,

Alistair



Re: [Qemu-devel] [PATCH] iscsi: Remember to set ret for iscsi_open in error case

2014-04-10 Thread Fam Zheng
On Thu, 04/10 13:11, Kevin Wolf wrote:
> Am 10.04.2014 um 03:33 hat Fam Zheng geschrieben:
> > Signed-off-by: Fam Zheng 
> 
> Thanks, applied to the block branch.
> 

Is this going into 2.0?

Thanks,
Fam



[Qemu-devel] [RFC PATCH] target-ppc: Relax use of generic CPU name for KVM

2014-04-10 Thread Alexey Kardashevskiy
At the moment generic version-less CPUs are supported via hardcoded aliases.
For example, POWER7 is an alias for POWER7_v2.1. So when QEMU is started
with -cpu POWER7, the POWER7_v2.1 class instance is created.

This approach works for TCG and KVMs other than HV KVM. HV KVM cannot emulate
PVR value so the guest always sees the real PVR. HV KVM will not allow setting
PVR other that the host PVR because of that (the kernel patch for it is on
its way). So in most cases it is impossible to run QEMU with -cpu POWER7
unless the host PVR is exactly the same as the one from the alias (which
is now POWER7_v2.3). It was decided that under HV KVM QEMU should use
-cpu host.

Using "host" CPU type creates a problem for management tools such as libvirt
because they want to know in advance if the destination guest can possibly
run on the destination. Since the "host" type is really not a type and will
always work with any KVM, there is no way for libvirt to know if the migration
will success.

This patch changes aliases handling by lowering their priority and adding
a new CPU generic class the same way as it is done for the "host" CPU class.

This registers additional CPU class derived from the host CPU family.
The name for it is taken from @desc field of the CPU family class.

This moves aliases lookup after CPU class lookup. This is to let new generic
CPU to be found first if it is present and only if it is not (TCG case), use
aliases.

Signed-off-by: Alexey Kardashevskiy 
---


!!! THIS IS NOT FOR 2.0 !!!

Just an RFC :)

Is that the right direction to go?

I would also remove POWER7_v2.0 and POWER7_v2.1 and leave just one versioned
CPU per family (which is POWER7_v2.3 with POWER7 alias). We do not emulate
these CPUs diffent so it does not make much sense to keep them, one per family
is perfectly enough.


---
 target-ppc/cpu-models.c |  4 
 target-ppc/cpu-models.h |  2 --
 target-ppc/kvm.c| 20 
 target-ppc/translate_init.c | 18 +++---
 4 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
index f6c9b3a..57cb4e4 100644
--- a/target-ppc/cpu-models.c
+++ b/target-ppc/cpu-models.c
@@ -1134,10 +1134,6 @@
 POWERPC_DEF("POWER6A",   CPU_POWERPC_POWER6A,POWER6,
 "POWER6A")
 #endif
-POWERPC_DEF("POWER7_v2.0",   CPU_POWERPC_POWER7_v20, POWER7,
-"POWER7 v2.0")
-POWERPC_DEF("POWER7_v2.1",   CPU_POWERPC_POWER7_v21, POWER7,
-"POWER7 v2.1")
 POWERPC_DEF("POWER7_v2.3",   CPU_POWERPC_POWER7_v23, POWER7,
 "POWER7 v2.3")
 POWERPC_DEF("POWER7+_v2.1",  CPU_POWERPC_POWER7P_v21,POWER7P,
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
index 644a126..9a003b4 100644
--- a/target-ppc/cpu-models.h
+++ b/target-ppc/cpu-models.h
@@ -555,8 +555,6 @@ enum {
 CPU_POWERPC_POWER6A= 0x0F02,
 CPU_POWERPC_POWER7_BASE= 0x003F,
 CPU_POWERPC_POWER7_MASK= 0x,
-CPU_POWERPC_POWER7_v20 = 0x003F0200,
-CPU_POWERPC_POWER7_v21 = 0x003F0201,
 CPU_POWERPC_POWER7_v23 = 0x003F0203,
 CPU_POWERPC_POWER7P_BASE   = 0x004A,
 CPU_POWERPC_POWER7P_MASK   = 0x,
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index ff952f0..b2e4db5 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1785,6 +1785,17 @@ bool kvmppc_has_cap_htab_fd(void)
 return cap_htab_fd;
 }
 
+static PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
+{
+ObjectClass *oc = OBJECT_CLASS(pcc);
+
+while (oc && !object_class_is_abstract(oc)) {
+oc = object_class_get_parent(oc);
+}
+
+return POWERPC_CPU_CLASS(oc);
+}
+
 static int kvm_ppc_register_host_cpu_type(void)
 {
 TypeInfo type_info = {
@@ -1794,6 +1805,7 @@ static int kvm_ppc_register_host_cpu_type(void)
 };
 uint32_t host_pvr = mfpvr();
 PowerPCCPUClass *pvr_pcc;
+DeviceClass *dc;
 
 pvr_pcc = ppc_cpu_class_by_pvr(host_pvr);
 if (pvr_pcc == NULL) {
@@ -1804,6 +1816,14 @@ static int kvm_ppc_register_host_cpu_type(void)
 }
 type_info.parent = object_class_get_name(OBJECT_CLASS(pvr_pcc));
 type_register(&type_info);
+
+/* Register generic family CPU class for a family */
+pvr_pcc = ppc_cpu_get_family_class(pvr_pcc);
+dc = DEVICE_CLASS(pvr_pcc);
+type_info.parent = object_class_get_name(OBJECT_CLASS(pvr_pcc));
+type_info.name = g_strdup_printf("%s-"TYPE_POWERPC_CPU, dc->desc);
+type_register(&type_info);
+
 return 0;
 }
 
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 4d94015..823c63c 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8218,12 +8218,6 @@ static ObjectClass *ppc_cpu_class_by_name(const char 
*name)
 }
 }
 
-for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
-  

[Qemu-devel] [PATCH] exit qemu when unknown object type is specified by -object

2014-04-10 Thread Hu Tao
...to avoid assertion failure in object_new_with_type(). Can be
reproduced by: qemu -object unknown-object,id=xxx

Signed-off-by: Hu Tao 
---
 qom/object.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/qom/object.c b/qom/object.c
index f4de619..1e7445b 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -448,6 +448,11 @@ Object *object_new(const char *typename)
 {
 TypeImpl *ti = type_get_by_name(typename);
 
+if (!ti) {
+error_report("unknown object type: %s\n", typename);
+exit(1);
+}
+
 return object_new_with_type(ti);
 }
 
-- 
1.8.5.2.229.g4448466




[Qemu-devel] [PATCH RFC V2] virtio-net: announce self by guest

2014-04-10 Thread Jason Wang
It's hard to track all mac addresses and their configurations (e.g
vlan or ipv6) in qemu. Without those informations, it's impossible to
build proper garp packet after migration. The only possible solution
to this is let guest (who knew all configurations) to do this.

So, this patch introduces a new readonly config status bit of virtio-net,
VIRTIO_NET_S_ANNOUNCE which is used to notify guest to announce
presence of its link through config update interrupt.When guest has
done the announcement, it should ack the notification through
VIRTIO_NET_CTRL_ANNOUNCE_ACK cmd. This feature is negotiated by a new
feature bit VIRTIO_NET_F_ANNOUNCE (which has already been supported by
Linux guest).

During load, a counter of announcing rounds were set so that the after
the vm is running it can trigger rounds of config interrupts to notify
the guest to build and send the correct garps.

Reference:
RFC v1: https://lists.gnu.org/archive/html/qemu-devel/2014-03/msg02648.html
V7: https://lists.gnu.org/archive/html/qemu-devel/2013-03/msg01127.html

Changes from RFC v1:
- clean VIRTIO_NET_S_ANNOUNCE bit during reset
- free announce timer during clean
- make announce work for non-vhost case

Changes from V7:
- Instead of introducing a global method for each kind of nic, this
  version limits the changes to virtio-net itself.

Cc: Liuyongan 
Cc: Amos Kong 
Signed-off-by: Jason Wang 
---
 hw/net/virtio-net.c|   48 
 include/hw/virtio/virtio-net.h |   16 +
 2 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 3626608..e2f0519 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -25,6 +25,7 @@
 #include "monitor/monitor.h"
 
 #define VIRTIO_NET_VM_VERSION11
+#define VIRTIO_NET_ANNOUNCE_ROUNDS3
 
 #define MAC_TABLE_ENTRIES64
 #define MAX_VLAN(1 << 12)   /* Per 802.1Q definition */
@@ -99,6 +100,25 @@ static bool virtio_net_started(VirtIONet *n, uint8_t status)
 (n->status & VIRTIO_NET_S_LINK_UP) && vdev->vm_running;
 }
 
+static void virtio_net_announce_timer(void *opaque)
+{
+VirtIONet *n = opaque;
+VirtIODevice *vdev = VIRTIO_DEVICE(n);
+
+if (n->announce &&
+virtio_net_started(n, vdev->status) &&
+vdev->guest_features & (0x1 << VIRTIO_NET_F_GUEST_ANNOUNCE) &&
+vdev->guest_features & (0x1 << VIRTIO_NET_F_CTRL_VQ)) {
+
+n->announce--;
+n->status |= VIRTIO_NET_S_ANNOUNCE;
+virtio_notify_config(vdev);
+} else {
+timer_del(n->announce_timer);
+n->announce = 0;
+}
+}
+
 static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(n);
@@ -147,6 +167,8 @@ static void virtio_net_set_status(struct VirtIODevice 
*vdev, uint8_t status)
 
 virtio_net_vhost_status(n, status);
 
+virtio_net_announce_timer(n);
+
 for (i = 0; i < n->max_queues; i++) {
 q = &n->vqs[i];
 
@@ -306,6 +328,9 @@ static void virtio_net_reset(VirtIODevice *vdev)
 n->nobcast = 0;
 /* multiqueue is disabled by default */
 n->curr_queues = 1;
+timer_del(n->announce_timer);
+n->announce = 0;
+n->status &= ~VIRTIO_NET_S_ANNOUNCE;
 
 /* Flush any MAC and VLAN filter table state */
 n->mac_table.in_use = 0;
@@ -710,6 +735,22 @@ static int virtio_net_handle_vlan_table(VirtIONet *n, 
uint8_t cmd,
 return VIRTIO_NET_OK;
 }
 
+static int virtio_net_handle_announce(VirtIONet *n, uint8_t cmd,
+  struct iovec *iov, unsigned int iov_cnt)
+{
+if (cmd == VIRTIO_NET_CTRL_ANNOUNCE_ACK) {
+n->status &= ~VIRTIO_NET_S_ANNOUNCE;
+if (n->announce) {
+timer_mod(n->announce_timer,
+  qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 50 +
+  (VIRTIO_NET_ANNOUNCE_ROUNDS - n->announce - 1) * 100);
+}
+return VIRTIO_NET_OK;
+} else {
+return VIRTIO_NET_ERR;
+}
+}
+
 static int virtio_net_handle_mq(VirtIONet *n, uint8_t cmd,
 struct iovec *iov, unsigned int iov_cnt)
 {
@@ -773,6 +814,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, 
VirtQueue *vq)
 status = virtio_net_handle_mac(n, ctrl.cmd, iov, iov_cnt);
 } else if (ctrl.class == VIRTIO_NET_CTRL_VLAN) {
 status = virtio_net_handle_vlan_table(n, ctrl.cmd, iov, iov_cnt);
+} else if (ctrl.class == VIRTIO_NET_CTRL_ANNOUNCE) {
+status = virtio_net_handle_announce(n, ctrl.cmd, iov, iov_cnt);
 } else if (ctrl.class == VIRTIO_NET_CTRL_MQ) {
 status = virtio_net_handle_mq(n, ctrl.cmd, iov, iov_cnt);
 } else if (ctrl.class == VIRTIO_NET_CTRL_GUEST_OFFLOADS) {
@@ -1418,6 +1461,7 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int 
version_id)
 qemu_get_subqueue(n->nic, i)->link_down = link_down;
 }
 
+n->announce = VIRTIO_NET_ANNOUNCE_ROUNDS;
   

Re: [Qemu-devel] [RFC v2 0/6] KVM platform device passthrough

2014-04-10 Thread Kim Phillips
On Wed, 9 Apr 2014 16:33:03 +0100
Eric Auger  wrote:

> some patches need to be applied on host linux to correct issues
> not yet upstreamed. They can be found on vfio-dev branch of
> git://git.linaro.org/people/eric.auger/linux.git
> 
> - commit 997691b: enables unmapping stage2 entries on memory region deletion
> - commit 731e308: corrects an in read/write function of vfio platform driver
> - iommu/arm-smmu commit serie and especially bf5a852 fixing an issue with
>   Calxeda Midway sMMU.

also these:

"ARM: KVM: Enable the KVM-VFIO device":
https://lists.cs.columbia.edu/pipermail/kvmarm/2014-March/008629.html

"ARM: KVM: user_mem_abort: support stage 2 MMIO page mapping":
https://lists.cs.columbia.edu/pipermail/kvmarm/2014-March/008630.html

Kim




Re: [Qemu-devel] qapi-commands.py generates code that uses uninitialized variables

2014-04-10 Thread Eric Blake
On 03/28/2014 08:19 AM, Peter Maydell wrote:
> On 20 March 2014 19:21, Michael Roth  wrote:
>> Could it be as simple as this?:
>>
>> diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
>> index 9734ab0..a70482e 100644
>> --- a/scripts/qapi-commands.py
>> +++ b/scripts/qapi-commands.py
>> @@ -99,7 +99,7 @@ bool has_%(argname)s = false;
>>   argname=c_var(argname), argtype=c_type(argtype))
>>  else:
>>  ret += mcgen('''
>> -%(argtype)s %(argname)s;
>> +%(argtype)s %(argname)s = {0};
>>  ''',
>>   argname=c_var(argname), argtype=c_type(argtype))
> 
> Well, clang doesn't complain about this syntax, and it
> fixes the warnings about bools (which is good, because
> there was a genuine bug in dma-helpers.c that was hiding
> in amongst these other similar warnings...)
> 
> Tested-by: Peter Maydell 

We uncovered a real bug that would be fixed by this patch:
https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg01745.html

Is it worth cleaning this up into a formal submission and cc'ing
qemu-stable and/or trying for the 2.0 release?  If made formal, feel
free to add:
Reviewed-by: Eric Blake 

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [RFC v2 4/6] vfio: Add initial IRQ support in QEMU platform device

2014-04-10 Thread Kim Phillips
On Wed, 9 Apr 2014 16:33:07 +0100
Eric Auger  wrote:

> This work is inspired of PCI INTx. The code was prepared to support
> multiple IRQs but this was not tested at that stage. Similarly to what
> is done on PCI, the device register space is RAM unmapped on IRQ hit
> in order to trap the end of interrupt (EOI). On mmap timer hit, if the
> EOI was trapped, the mmapping is restored. the physical interrupt is
> unmasked on the first read/write with the MMIO register space.
> 
> Tested on Calxeda Midway xgmac which can be directly assigned to one
> virt VM.
> 
> Acknowledgements:
> - vfio device name, guest physical address and IRQ indexes are
>   hardcoded. This will be improved in another patch
> - currently tested on a single IRQ (xgmac main IRQ)
> - a KVM patch is required to invalidate stage2 entries on RAM memory
>   region destruction (see [PATCH] ARM: KVM: Handle IPA unmapping on
>   memory region deletion)
> 
> Signed-off-by: Eric Auger 
> ---

thanks for this, Eric.

>  hw/arm/virt.c  |  13 ++-
>  hw/vfio/platform.c | 316 
> +
>  2 files changed, 304 insertions(+), 25 deletions(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 5d43cf0..31ae7d2 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -108,12 +108,13 @@ static const MemMapEntry a15memmap[] = {
>  /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size 
> */
>  /* 0x1000 .. 0x4000 reserved for PCI */
>  [VIRT_MEM] = { 0x4000, 1ULL * 1024 * 1024 * 1024 },
> -[VIRT_ETHERNET] = { 0xfff51000, 0x1000 },
> +[VIRT_ETHERNET] = { 0xfff41000, 0x1000 },

this change isn't explained (the device is at physical 0xfff51000,
not 0xfff41000), and looks like it belongs in the first patch of the
series anyway.   Note: see e.g., commit f5fdcd6e5 "hw/arm: Add
'virt' platform" for an example of how to re-compose commit message
text for patches that undergo a change of author.

>  };
>  
>  static const int a15irqmap[] = {
>  [VIRT_UART] = 1,
>  [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
> +[VIRT_ETHERNET] = 77,
>  };
>  
>  static VirtBoardInfo machines[] = {
> @@ -299,8 +300,12 @@ static void create_ethernet(const VirtBoardInfo *vbi, 
> qemu_irq *pic)
>  hwaddr base = vbi->memmap[VIRT_ETHERNET].base;
>  hwaddr size = vbi->memmap[VIRT_ETHERNET].size;
>  const char compat[] = "calxeda,hb-xgmac";
> +int irqm = vbi->irqmap[VIRT_ETHERNET];
> +int irqp = irqm+1;
> +int irqlp = irqm+2;
>  
> -sysbus_create_simple("vfio-platform", base, NULL);
> +sysbus_create_varargs("vfio-platform", base,
> +  pic[irqm], pic[irqp], pic[irqlp], NULL);
>  
>  nodename = g_strdup_printf("/ethernet@%" PRIx64, base);
>  qemu_fdt_add_subnode(vbi->fdt, nodename);
> @@ -308,6 +313,10 @@ static void create_ethernet(const VirtBoardInfo *vbi, 
> qemu_irq *pic)
>  /* Note that we can't use setprop_string because of the embedded NUL */
>  qemu_fdt_setprop(vbi->fdt, nodename, "compatible", compat, 
> sizeof(compat));
>  qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg", 2, base, 2, 
> size);
> +qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
> +0x0, irqm, 0x4,
> +0x0, irqp, 0x4,
> +0x0, irqlp, 0x4);

fwiw, it would have been nice to reuse the irq variable names used
in hw/net/xgmac.c, but whatever...

>  g_free(nodename);
>  }
> diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
> index 138fb13..f148edd 100644
> --- a/hw/vfio/platform.c
> +++ b/hw/vfio/platform.c
> @@ -24,6 +24,7 @@
>  #include "config.h"
>  #include "exec/address-spaces.h"
>  #include "exec/memory.h"
> +
>  #include "qemu-common.h"
>  #include "qemu/error-report.h"
>  #include "qemu/event_notifier.h"
> @@ -31,6 +32,7 @@
>  #include "qemu/range.h"
>  #include "sysemu/kvm.h"
>  #include "sysemu/sysemu.h"
> +
>  #include "hw/qdev-properties.h"
>  #include "migration/vmstate.h"
>  #include "hw/hw.h"
> @@ -41,12 +43,15 @@
>  #define DEBUG_VFIO
>  #ifdef DEBUG_VFIO
>  #define DPRINTF(fmt, ...) \
> -do { fprintf(stderr, "vfio: " fmt, ## __VA_ARGS__); } while (0)
> +do { fprintf(stderr, "vfio: %s: " fmt, __func__, ## __VA_ARGS__); } \
> +while (0)

these changes are unrelated to the subject of this "add IRQ" patch -
either make them their own patch (in between the last one and this
one), or merge them with the prior patch (that introduces the code),
but since their nature starts to drift from the corresponding PCI
code counterpart, I can't help think why they shouldn't be applied
there, too.  Probably best dropping them for now - these and
cleaning up more of the superfluous DPRINTFs added in this series.

>  #else
>  #define DPRINTF(fmt, ...) \
>  do { } while (0)
>  #endif
>  
> +#define PLATFORM_NUM_REGIONS 10
> +

this is a regression from the third patch in this series - see 

Re: [Qemu-devel] [Qemu-stable] [PATCH] block-commit: speed is an optional parameter

2014-04-10 Thread Eric Blake
On 04/10/2014 07:09 PM, Fam Zheng wrote:
> On Thu, 04/10 19:36, Max Reitz wrote:
>> As speed is an optional parameter for the QMP block-commit command, it
>> should be set to 0 if not given (as it is undefined if has_speed is
>> false), that is, the speed should not be limited.
>>
>> Signed-off-by: Max Reitz 
>> Reviewed-by: Eric Blake 
>> ---
>> This patch was previously part of the "qemu-img: Implement commit like
>> QMP" series, but as this is a general bugfix, it has been separated.
>> ---
> 
> Reviewed-by: Fam Zheng 
> 
> The (generated) caller qmp_marshal_input_block_commit() actually leaves speed
> uninitialized, so we're not safe without this patch:

> I'm wondering what the reason is to initialize pointers (like base and device)
> while leaving int64_t values uninitilized in the code generator?

Because no one has applied this patch yet:

https://lists.gnu.org/archive/html/qemu-devel/2014-03/msg04224.html

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [Qemu-stable] [PATCH] block-commit: speed is an optional parameter

2014-04-10 Thread Fam Zheng
On Thu, 04/10 19:36, Max Reitz wrote:
> As speed is an optional parameter for the QMP block-commit command, it
> should be set to 0 if not given (as it is undefined if has_speed is
> false), that is, the speed should not be limited.
> 
> Signed-off-by: Max Reitz 
> Reviewed-by: Eric Blake 
> ---
> This patch was previously part of the "qemu-img: Implement commit like
> QMP" series, but as this is a general bugfix, it has been separated.
> ---

Reviewed-by: Fam Zheng 

The (generated) caller qmp_marshal_input_block_commit() actually leaves speed
uninitialized, so we're not safe without this patch:

int qmp_marshal_input_block_commit(Monitor *mon, const QDict *qdict, QObject 
**ret)
{
Error *local_err = NULL;
Error **errp = &local_err;
QDict *args = (QDict *)qdict;
QmpInputVisitor *mi;
QapiDeallocVisitor *md;
Visitor *v;
char * device = NULL;
bool has_base = false;
char * base = NULL;
char * top = NULL;
bool has_speed = false;
int64_t speed;

I'm wondering what the reason is to initialize pointers (like base and device)
while leaving int64_t values uninitilized in the code generator?

Fam

>  blockdev.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/blockdev.c b/blockdev.c
> index c3422a1..5dd01ea 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -1876,6 +1876,10 @@ void qmp_block_commit(const char *device,
>   */
>  BlockdevOnError on_error = BLOCKDEV_ON_ERROR_REPORT;
>  
> +if (!has_speed) {
> +speed = 0;
> +}
> +
>  /* drain all i/o before commits */
>  bdrv_drain_all();
>  
> -- 
> 1.9.1
> 
> 



Re: [Qemu-devel] [PATCH v2 4/5] block: qemu-iotests - fix image cleanup when using spaced pathnames

2014-04-10 Thread Fam Zheng
On Thu, 04/10 14:09, Jeff Cody wrote:
> On Thu, Apr 10, 2014 at 08:48:10AM -0600, Eric Blake wrote:
> > On 04/10/2014 08:43 AM, Eric Blake wrote:
> > > On 04/10/2014 06:53 AM, Jeff Cody wrote:
> > > 
> >  +++ b/tests/qemu-iotests/common.rc
> >  @@ -178,10 +178,10 @@ _rm_test_img()
> >   local img=$1
> > >>>
> > >>> Since we are quoting $img, should we quote $1 as well?
> > >>>
> > 
> > > 
> > > http://austingroupbugs.net/view.php?id=351
> > > 
> > > But even with the notion of an assignment-context argument added to a
> > > future version of POSIX, the reality is that given the present standard,
> > > it's safer to either use "" to ensure no word splitting:
> > 
> > Well, if you were trying to be portable to multiple shells, then it
> > would matter.  But as this script is explicitly being run under
> > /bin/bash, and as bash already has support for declaration utilities
> > where local is one such utility, your script as written is safe without
> > "" in the arguments to local.  So I'm fine whether you choose to change
> > it in a respin or to leave it as written in this version.

Thanks for the thorough explanation, Eric!

> 
> Hi Eric,
> 
> Thanks - I consulted specifically with just the bash documentation, so
> you are right, this script (and likely most of qemu-iotests) is
> bash-only.
> 
> That particular line is context as well, and not an actual change - so
> while it may be a good idea to quote it to make the scripts closer to
> posix-only, my guess is there are quite a few similar lines throughout
> all the qemu-iotests scripts.
> 
> Given that, if we address that it would probably make sense to do that
> in a bash->posix conversion series for all the scripts (likely a low
> priority, however).
> 

OK :)

Thanks,
Fam



Re: [Qemu-devel] [PATCH v1 1/1] vl.c: Allow sysbus devices to be attached via commandline

2014-04-10 Thread Peter Crosthwaite
cc Alex

On Thu, Apr 10, 2014 at 10:54 AM, Alistair Francis
 wrote:
> On Wed, Apr 9, 2014 at 6:02 PM, Markus Armbruster  wrote:
>> Alistair Francis  writes:
>>
>>> On Wed, Apr 9, 2014 at 11:28 AM, Peter Crosthwaite
>>>  wrote:
 On Wed, Mar 26, 2014 at 10:47 AM, Alistair Francis
  wrote:
> This patch introduces a new command line argument that allows
> sysbus devices to be attached via the command line.
>
> This allows devices to be added after the machine init but
> before anything is booted
>
> The new argument is -sysbusdev
>
> A new argument is being used to avoid confusion and user
> errors that would appear if the same command for hot-plugging
> was used instead. This could be changed to use -device and
> specify sysbus by using something like 'bus=sysbus' if that
> is preferred
>

 Can you be more specific about the confusion issue you are seeing? If
 you went for -device bus=root (meaning the default singleton root
 sysbus), where are the possible issues?

>>>
>>> Using -device would be possible (and easy to implement). The reason I
>>> started with
>>> a different argument name was just to avoid confusion and to make sure
>>> I didn't interfere with hot-pluggable devices. I still feel that separating
>>> hot-pluggable devices from bus devices is a good idea. They are initialised
>>> in slightly different parts of the code (although this wouldn't
>>> be hard to fix). The name 'sysbusdev' is confusing though, as it doesn't
>>> have to connect to the sysbus.
>>
>> -device / device_add already covers both hot plug and cold plug.  In
>> fact, only device_add can hot plug; all -device ever does is cold plug.
>>
>> Plugging in a device involves wiring it up.  Hot plug additionally
>> involves communication with guest software, but let's ignore that for
>> now.
>>
>> -device uses generic wiring code, guided by configuration: property
>> "bus".  This suffices for straightforward cases like PCI and USB
>> devices.  It doesn't for sysbus devices, because these may require
>> arbitrarily complex wirings.  Therefore, sysbus devices are unavailable
>> with -device; see commit 837d371.
>>
>> What we need is a way for configuration to guide more general wiring.
>> Perhaps -device can be extended.  If that turns out to be impractical,
>> we need something more expressive that also covers everything -device
>> does now, and can cover "everything" eventually.  Andreas may have ideas
>> here.
>
> I have managed to extended -device to allow QOM devices to be attached
> to the system bus.
> I removed the -sysbusdev argument and am now back to just using
> "-device" where the
> user can specify which bus to connect to.
> This allows entire machines to be built from command line arguments
> using "-M none".
>
> I'm just tidying up the patch now
>
>>
>> What we don't need, in my opinion, is more special-case options :)
>>
>> [...]
>>
>



Re: [Qemu-devel] [PATCH v6 00/37] AArch64 system emulation

2014-04-10 Thread Peter Crosthwaite
On Fri, Apr 11, 2014 at 2:14 AM, Peter Maydell  wrote:
> Here's v5 of the AArch64 system emulation patchset.
> Still missing/TODO:
>  * SMP support (needs PSCI emulation in QEMU; being prototyped)
>  * save/restore (I have a patch which adds this but I think it will
>look better if we consolidate AArch32 cpsr and AArch64 pstate
>handling)
> but both of these I think are best done once this main series
> is committed to master.
>
> The changes v5->v6 are pretty minor, and these patches have
> been kicking around onlist for a long time, so I plan to
> put these in a pull request pretty much as soon as we reopen
> trunk after 2.0 releases. Last chance for review!
>

Ill do another sweep before the end of the week and review those Ive
skipped over so far for completeness.

Regards,
Peter

>
> Changes v5->v6:
>  * add extract64() when putting together 32-bit CBAR value
>  * be consistent about int vs bool for 1 bit fields in the
>syn_insn_abort/syn_data_abort functions
>  * added some FIXMEs about inaccurate syndrome info for A32/T32
>Neon unallocated insns when FP is disabled
>  * decided that using a15mpcore_priv in the virt machine is actually
>the best approach, and added a suitable comment
> Changes v4->v5:
>  * new patches:
>+ MVFR registers
>+ various extra system registers
>+ don't expose wildcards for ARMv8
>+ make A15's CBAR R/O
>+ support interprocessing in set_pc
>  * minor tweaks per review (I haven't always taken the review
>suggestion; see mail threads on the previous version of the
>patch series)
>  * DC ZVA: use helper_ret_stb_mmu
>make tlb_vaddr_to_host take param for access type
>  * NB: I didn't make gen_exception and gen_exception_internal shared
>in patch 5: I think keeping the A64 and A32 decoders independent
>is preferable
>  * have syn_insn_abort and syn_data_abort set the syndrome bit
>for 'exception to same level' rather than making caller do it
> Changes v3->v4:
>  * reviewed patches from bottom of stack got committed to master
>  * new patches at top of stack
>  * addressed review issues on v8 mmu translation patch and DAIF patch
>
> thanks
> -- PMM
>
>
> Peter Maydell (33):
>   target-arm: Split out private-to-target functions into internals.h
>   target-arm: Implement AArch64 DAIF system register
>   target-arm: Define exception record for AArch64 exceptions
>   target-arm: Provide correct syndrome information for cpreg access
> traps
>   target-arm: Add support for generating exceptions with syndrome
> information
>   target-arm: A64: Correctly fault FP/Neon if CPACR.FPEN set
>   target-arm: A64: Add assertion that FP access was checked
>   target-arm: Fix VFP enables for AArch32 EL0 under AArch64 EL1
>   target-arm: Don't mention PMU in debug feature register
>   target-arm: A64: Implement DC ZVA
>   target-arm: Use dedicated CPU state fields for ARM946 access bit
> registers
>   target-arm: Add AArch64 ELR_EL1 register.
>   target-arm: Implement SP_EL0, SP_EL1
>   target-arm: Implement AArch64 SPSR_EL1
>   target-arm: Move arm_log_exception() into internals.h
>   target-arm: Implement ARMv8 MVFR registers
>   target-arm: Add Cortex-A57 processor
>   hw/arm/virt: Add support for Cortex-A57
>   target-arm: Implement AArch64 views of AArch32 ID registers
>   target-arm: Implement AArch64 view of CONTEXTIDR
>   target-arm: Implement AArch64 view of ACTLR
>   target-arm: Implement ISR_EL1 register
>   target-arm: Remove THUMB2EE feature from AArch64 'any' CPU
>   target-arm: Don't expose wildcard ID register definitions for ARMv8
>   target-arm: Replace wildcarded cpreg definitions with precise ones for
> ARMv8
>   target-arm: Implement auxiliary fault status registers
>   target-arm: Implement AArch64 address translation operations
>   target-arm: Implement RVBAR register
>   target-arm: Implement Cortex-A57 implementation-defined system
> registers
>   target-arm: Implement CBAR for Cortex-A57
>   target-arm: Make Cortex-A15 CBAR read-only
>   target-arm: Handle the CPU being in AArch32 mode in the AArch64 set_pc
>   target-arm: Dump 32-bit CPU state if 64 bit CPU is in AArch32
>
> Rob Herring (4):
>   target-arm: Provide syndrome information for MMU faults
>   target-arm: Add v8 mmu translation support
>   target-arm: Implement AArch64 views of fault status and data registers
>   target-arm: Implement AArch64 EL1 exception handling
>
>  hw/arm/virt.c   |   8 +
>  include/exec/softmmu_exec.h |  52 +++
>  linux-user/main.c   |  56 ++-
>  target-arm/cpu-qom.h|  10 +-
>  target-arm/cpu.c|  30 +-
>  target-arm/cpu.h|  81 +++--
>  target-arm/cpu64.c  | 115 ++-
>  target-arm/helper-a64.c |  75 
>  target-arm/helper.c | 809 
> +---
>  target-arm/helper.h |   7 +-
>  target-arm/internals.h  | 267 +++
>  target-arm/kvm32.c  |  19 +-
>  target-arm/kvm

Re: [Qemu-devel] [PULL for-2.0 v2 0/2] acpi: DSDT update

2014-04-10 Thread Peter Maydell
On 10 April 2014 17:12, Michael S. Tsirkin  wrote:
> The following changes since commit efcc87d9aedb590b8506cd1a7c8abe557c760f9e:
>
>   Update version for v2.0.0-rc2 release (2014-04-08 18:52:06 +0100)
>
> are available in the git repository at:
>
>   git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
>
> for you to fetch changes up to 775478418a5244b28ce891e398e0232dc4e60b43:
>
>   acpi: update generated hex files (2014-04-10 19:03:18 +0300)

Applied, thanks.

-- PMM



Re: [Qemu-devel] [PATCH for-2.0] configure: use do_cc when checking for -fstack-protector support

2014-04-10 Thread Peter Maydell
On 10 April 2014 18:51, Michael S. Tsirkin  wrote:
> Reviewed-by: Michael S. Tsirkin 

Thanks; patch applied to master.

-- PMM



Re: [Qemu-devel] Should we have a 2.0-rc3 ?

2014-04-10 Thread Peter Maydell
On 10 April 2014 12:17, Peter Maydell  wrote:
> So far I know of at least three fixes which should probably
> go into 2.0:
>  * my fix for the configure stack-protector checks on MacOSX
>  * MST's pull request updating the ACPI test blobs
>  * MST says we need to update the hex files for ACPI too
>(otherwise you get a different ACPI blob depending on whether
> your build system had iasl or not, if I understand correctly)
>
> Are there any others?
>
> So we have two choices:
>
> (A) get those fixes into git today, and tag an rc3; that
> would then need some testing time and presumably we'd hope
> to tag it as the 2.0 release on Monday or Tuesday next week
>
> (B) say that the above are not worth fixing in 2.0 proper
> and plan to do a 2.0.1 in a few weeks with the above plus
> any other breakage that people find.

OK, consensus seems to be that we have enough
showstoppers to merit an rc3. I'm going to start
applying the fixes we have; if we can get fixes for
the others by tomorrow (Friday) we can maybe do
the rc3 tag then.

thanks
-- PMM



Re: [Qemu-devel] [PATCH v4 21/21] hw/arm/virt: Add support for Cortex-A57

2014-04-10 Thread Peter Maydell
On 10 April 2014 20:41, Rob Herring  wrote:
> On Thu, Apr 10, 2014 at 10:02 AM, Peter Maydell
>  wrote:
>> We could in theory write an a57mpcore_priv which was a
>> carbon copy of a15mpcore_priv, but that seems a bit pointless.
>> I think it's probably actually reasonable to use a15mpcore_priv
>> here, with an appropriate comment:
>>
>> /* Our A57 has an A15-style GICv2, so we can use a15mpcore_priv */
>
> I think there are 3 possibilities of what actual h/w may look like. i
> agree this is the correct thing to do for one case (and is the only
> one qemu is able to support today). The others are:
>
> A57 + SBSA compliant GICv2(M)
> A57 + GICv3
>
> The SBSA change is making each register bank within the GIC 64K spaced
> instead of 4K spaced to support 64KB pages in OSs and hypervisors.

That part is pretty easy to do in QEMU -- we'd just need a suitable
container object that mapped the GIC regions in different locations.
It might be worth doing that now rather than putting this in and
then changing it later.

> This is a simple address swizzling trick defined in the SBSA doc.
> (Since it's documented it must not be a cute embedded nonsense hack.
> :)) Then the M portion is for PCI MSI support which is optional.

I haven't looked too closely at the GICv2M spec but it probably
is not too hard (certainly in comparison to the v3 GIC ;-))

thanks
-- PMM



Re: [Qemu-devel] [PATCH] Keyboard/Mouse Console for vfio with active function x-vga ans -vga none

2014-04-10 Thread qemu Mailinglist

Am 10.04.2014 22:29, schrieb Alex Williamson:
> I don't think vfio is the one to be creating a dummy console, besides
> there's no reason you can't have multiple vfio devices with x-vga=on.
> There should probably be some dummy console driver so you can add
> -device dummy-console to the commandline if this is desired.  Thanks,
>
> Alex
Hi Alex,

thanks for the fast answer, I had no luck with the dummy devices, so I
have to forward additional input devices via usbpassthru or pcipassthru
of a USB Card.

The other console_inits are in the device files like: ( some from 30
files total)
./hw/unicore32/puv3.c:101:graphic_console_init(NULL, 0, &no_ops, NULL);
./hw/display/pl110.c:467:s->con = graphic_console_init(dev, 0,
&pl110_gfx_ops, s);
./hw/display/vga-isa-mm.c:138:s->vga.con =
graphic_console_init(NULL, 0, s->vga.hw_ops, s);
./hw/display/exynos4210_fimd.c:1920:s->console =
graphic_console_init(DEVICE(dev), 0, &exynos4210_fimd_ops, s);
./hw/display/vmware_vga.c:1203:s->vga.con =
graphic_console_init(dev, 0, &vmsvga_ops, s);
./hw/display/cirrus_vga.c:2920:s->con = graphic_console_init(dev, 0,
s->hw_ops, s);
./hw/display/cirrus_vga.c:2966: s->vga.con =
graphic_console_init(DEVICE(dev), 0, s->vga.hw_ops, &s->vga);
./hw/display/vga-pci.c:154:s->con =
graphic_console_init(DEVICE(dev), 0, s->hw_ops, s);

But you are right, its more a feature with a additional parameter for x-vga.

Thanks,
 Tobias



[Qemu-devel] [PATCH v3 5/5] block: qemu-iotests: make test 019 and 086 work with spaced pathnames

2014-04-10 Thread Jeff Cody
Both tests 019 and 086 need proper quotations to work with pathnames
that contain spaces.

Reviewed-by: Benoit Canet 
Reviewed-by: Fam Zheng 
Signed-off-by: Jeff Cody 
---
 tests/qemu-iotests/019 | 2 +-
 tests/qemu-iotests/086 | 8 
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/tests/qemu-iotests/019 b/tests/qemu-iotests/019
index e67445c..f5ecbf5 100755
--- a/tests/qemu-iotests/019
+++ b/tests/qemu-iotests/019
@@ -96,7 +96,7 @@ mv "$TEST_IMG" "$TEST_IMG.orig"
 for backing_option in "-B " "-o backing_file="; do
 
 echo
-echo Testing conversion with $backing_option$TEST_IMG.base | 
_filter_testdir | _filter_imgfmt
+echo Testing conversion with $backing_option"$TEST_IMG.base" | 
_filter_testdir | _filter_imgfmt
 echo
 $QEMU_IMG convert -O $IMGFMT $backing_option"$TEST_IMG.base" 
"$TEST_IMG.orig" "$TEST_IMG"
 
diff --git a/tests/qemu-iotests/086 b/tests/qemu-iotests/086
index 48fe85b..d9a80cf 100755
--- a/tests/qemu-iotests/086
+++ b/tests/qemu-iotests/086
@@ -51,10 +51,10 @@ function run_qemu_img()
 size=128M
 
 _make_test_img $size
-$QEMU_IO -c 'write 0 1M' $TEST_IMG | _filter_qemu_io
-$QEMU_IO -c 'write 2M 1M' $TEST_IMG | _filter_qemu_io
-$QEMU_IO -c 'write 4M 1M' $TEST_IMG | _filter_qemu_io
-$QEMU_IO -c 'write 32M 1M' $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c 'write 0 1M' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c 'write 2M 1M' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c 'write 4M 1M' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c 'write 32M 1M' "$TEST_IMG" | _filter_qemu_io
 
 $QEMU_IMG convert -p -O $IMGFMT -f $IMGFMT "$TEST_IMG" "$TEST_IMG".base  2>&1 
|\
 _filter_testdir | sed -e 's/\r/\n/g'
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 4/5] block: qemu-iotests - fix image cleanup when using spaced pathnames

2014-04-10 Thread Jeff Cody
The _rm_test_img() function in common.rc did not quote the image
file, which left droppings in the scratch directory (and performed
a potentially unsafe rm -f).

This adds the necessary quotes.

Reviewed-by: Benoit Canet 
Signed-off-by: Jeff Cody 
---
 tests/qemu-iotests/common.rc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 7f00883..195c564 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -178,10 +178,10 @@ _rm_test_img()
 local img=$1
 if [ "$IMGFMT" = "vmdk" ]; then
 # Remove all the extents for vmdk
-$QEMU_IMG info $img 2>/dev/null | grep 'filename:' | cut -f 2 -d: \
+"$QEMU_IMG" info "$img" 2>/dev/null | grep 'filename:' | cut -f 2 -d: \
 | xargs -I {} rm -f "{}"
 fi
-rm -f $img
+rm -f "$img"
 }
 
 _cleanup_test_img()
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 3/5] block: qemu-iotests - test for live migration

2014-04-10 Thread Jeff Cody
This is an initial, simple live migration test from one
running VM to another, using monitor commands.

This is also an example on using the new common.qemu functions
for controlling multiple running qemu instances, for tests that
need a live qemu vm.

Signed-off-by: Jeff Cody 
---
 tests/qemu-iotests/090 | 97 ++
 tests/qemu-iotests/090.out | 20 ++
 tests/qemu-iotests/group   |  1 +
 3 files changed, 118 insertions(+)
 create mode 100755 tests/qemu-iotests/090
 create mode 100644 tests/qemu-iotests/090.out

diff --git a/tests/qemu-iotests/090 b/tests/qemu-iotests/090
new file mode 100755
index 000..22a7cf1
--- /dev/null
+++ b/tests/qemu-iotests/090
@@ -0,0 +1,97 @@
+#!/bin/bash
+#
+# Live migration test
+#
+# Performs a migration from one VM to another via monitor commands
+#
+# Copyright (C) 2014 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+# creator
+owner=jc...@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1   # failure is the default!
+
+MIG_FIFO="${TEST_DIR}/migrate"
+
+_cleanup()
+{
+rm -f "${MIG_FIFO}"
+_cleanup_qemu
+   _cleanup_test_img
+
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.qemu
+
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+
+size=1G
+
+IMGOPTS="cluster_size=512" _make_test_img $size
+
+mkfifo "${MIG_FIFO}"
+
+echo
+echo === Starting QEMU VM1 ===
+echo
+
+qemu_comm_method="monitor"
+_launch_qemu -drive file="${TEST_IMG}",cache=none,id=disk
+h1=$QEMU_HANDLE
+
+echo
+echo === Starting QEMU VM2 ===
+echo
+_launch_qemu -drive file="${TEST_IMG}",cache=none,id=disk \
+ -incoming "exec: cat '${MIG_FIFO}'"
+h2=$QEMU_HANDLE
+
+echo
+echo === VM 1: Migrate from VM1 to VM2  ===
+echo
+
+silent=yes
+_send_qemu_cmd $h1 'qemu-io disk "write 0 4M"' "(qemu)"
+echo "vm1: qemu-io disk write complete"
+_send_qemu_cmd $h1 "migrate \"exec: cat > '${MIG_FIFO}'\"" "(qemu)"
+echo "vm1: live migration started"
+qemu_cmd_repeat=20 _send_qemu_cmd $h1 "info migrate" "completed"
+echo "vm1: live migration completed"
+
+echo
+echo === VM 2: Post-migration, write to disk, verify running ===
+echo
+
+_send_qemu_cmd $h2 'qemu-io disk "write 4M 1M"' "(qemu)"
+echo "vm2: qemu-io disk write complete"
+qemu_cmd_repeat=20 _send_qemu_cmd $h2 "info status" "running"
+echo "vm2: qemu process running successfully"
+
+
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/090.out b/tests/qemu-iotests/090.out
new file mode 100644
index 000..e965dfd
--- /dev/null
+++ b/tests/qemu-iotests/090.out
@@ -0,0 +1,20 @@
+QA output created by 090
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
+
+=== Starting QEMU VM1 ===
+
+
+=== Starting QEMU VM2 ===
+
+
+=== VM 1: Migrate from VM1 to VM2 ===
+
+vm1: qemu-io disk write complete
+vm1: live migration started
+vm1: live migration completed
+
+=== VM 2: Post-migration, write to disk, verify running ===
+
+vm2: qemu-io disk write complete
+vm2: qemu process running successfully
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 864643d..4386008 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -95,3 +95,4 @@
 086 rw auto quick
 087 rw auto
 088 rw auto
+090 rw auto
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 2/5] block: qemu-iotests - update 085 to use common.qemu

2014-04-10 Thread Jeff Cody
The new functionality of common.qemu implements the QEMU control
and communication functionality that was originally in test 085.

This removes that now-duplicate functionality, and uses the
common.qemu functions.

Reviewed-by: Benoit Canet 
Signed-off-by: Jeff Cody 
---
 tests/qemu-iotests/085 | 73 +-
 1 file changed, 12 insertions(+), 61 deletions(-)

diff --git a/tests/qemu-iotests/085 b/tests/qemu-iotests/085
index 33c8dc4..56cd6f8 100755
--- a/tests/qemu-iotests/085
+++ b/tests/qemu-iotests/085
@@ -30,10 +30,6 @@ echo "QA output created by $seq"
 
 here=`pwd`
 status=1   # failure is the default!
-qemu_pid=
-
-QMP_IN="${TEST_DIR}/qmp-in-$$"
-QMP_OUT="${TEST_DIR}/qmp-out-$$"
 
 snapshot_virt0="snapshot-v0.qcow2"
 snapshot_virt1="snapshot-v1.qcow2"
@@ -42,10 +38,7 @@ MAX_SNAPSHOTS=10
 
 _cleanup()
 {
-kill -KILL ${qemu_pid}
-wait ${qemu_pid} 2>/dev/null  # silent kill
-
-rm -f "${QMP_IN}" "${QMP_OUT}"
+_cleanup_qemu
 for i in $(seq 1 ${MAX_SNAPSHOTS})
 do
 rm -f "${TEST_DIR}/${i}-${snapshot_virt0}"
@@ -59,43 +52,12 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
+. ./common.qemu
 
 _supported_fmt qcow2
 _supported_proto file
 _supported_os Linux
 
-# Wait for expected QMP response from QEMU.  Will time out
-# after 10 seconds, which counts as failure.
-#
-# $1 is the string to expect
-#
-# If $silent is set to anything but an empty string, then
-# response is not echoed out.
-function timed_wait_for()
-{
-while read -t 10 resp <&5
-do
-if [ "${silent}" == "" ]; then
-echo "${resp}" | _filter_testdir | _filter_qemu
-fi
-grep -q "${1}" < <(echo ${resp})
-if [ $? -eq 0 ]; then
-return
-fi
-done
-echo "Timeout waiting for ${1}"
-exit 1  # Timeout means the test failed
-}
-
-# Sends QMP command to QEMU, and waits for the expected response
-#
-# ${1}:  String of the QMP command to send
-# ${2}:  String that the QEMU response should contain
-function send_qmp_cmd()
-{
-echo "${1}" >&6
-timed_wait_for "${2}"
-}
 
 # ${1}: unique identifier for the snapshot filename
 function create_single_snapshot()
@@ -104,7 +66,7 @@ function create_single_snapshot()
   'arguments': { 'device': 'virtio0',
  
'snapshot-file':'"${TEST_DIR}/${1}-${snapshot_virt0}"',
  'format': 'qcow2' } }"
-send_qmp_cmd "${cmd}" "return"
+_send_qemu_cmd $h "${cmd}" "return"
 }
 
 # ${1}: unique identifier for the snapshot filename
@@ -120,14 +82,11 @@ function create_group_snapshot()
'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt1}"' 
} } ]
  } }"
 
-send_qmp_cmd "${cmd}" "return"
+_send_qemu_cmd $h "${cmd}" "return"
 }
 
 size=128M
 
-mkfifo "${QMP_IN}"
-mkfifo "${QMP_OUT}"
-
 _make_test_img $size
 mv "${TEST_IMG}" "${TEST_IMG}.orig"
 _make_test_img $size
@@ -136,23 +95,15 @@ echo
 echo === Running QEMU ===
 echo
 
-"${QEMU}" -nographic -monitor none -serial none -qmp stdio\
-  -drive file="${TEST_IMG}.orig",if=virtio\
-  -drive file="${TEST_IMG}",if=virtio 2>&1 >"${QMP_OUT}" <"${QMP_IN}"&
-qemu_pid=$!
-
-# redirect fifos to file descriptors, to keep from blocking
-exec 5<"${QMP_OUT}"
-exec 6>"${QMP_IN}"
-
-# Don't print response, since it has version information in it
-silent=yes timed_wait_for "capabilities"
+qemu_comm_method="qmp"
+_launch_qemu -drive file="${TEST_IMG}.orig",if=virtio -drive 
file="${TEST_IMG}",if=virtio
+h=$QEMU_HANDLE
 
 echo
 echo === Sending capabilities ===
 echo
 
-send_qmp_cmd "{ 'execute': 'qmp_capabilities' }" "return"
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return"
 
 echo
 echo === Create a single snapshot on virtio0 ===
@@ -165,16 +116,16 @@ echo
 echo === Invalid command - missing device and nodename ===
 echo
 
-send_qmp_cmd "{ 'execute': 'blockdev-snapshot-sync',
-  'arguments': { 
'snapshot-file':'"${TEST_DIR}"/1-${snapshot_virt0}',
+_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
+ 'arguments': { 
'snapshot-file':'"${TEST_DIR}/1-${snapshot_virt0}"',
  'format': 'qcow2' } }" "error"
 
 echo
 echo === Invalid command - missing snapshot-file ===
 echo
 
-send_qmp_cmd "{ 'execute': 'blockdev-snapshot-sync',
-  'arguments': { 'device': 'virtio0',
+_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
+ 'arguments': { 'device': 'virtio0',
  'format': 'qcow2' } }" "error"
 echo
 echo
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 0/5] Add common QEMU control functionality to qemu-iotests

2014-04-10 Thread Jeff Cody
Changes from v2:

Updated Reviewed-by for Fam and Benoit (Benoit's from the v1 patch, I forgot to
add those to v2)

Patch 1: * updated commit message (Thanks Fam)
 * Addded '-machine accel=qtest' to qemu launch args (Thanks Fam)
Patch 3: * Moved from test 089 -> test 090 to avoid collision with
   Fam's series (Thanks Fam)

Changes from v1:

Patch 1: * Fixed commit message, clarified comments (Thanks Benoît)
 * Changed 'shift' line to be POSIX-friendly, instead of
   relying on bashism (Thanks Eric)
 * Added ability to repeat qmp or hmp commands an arbitrary
   number of times
Patch 3: New patch, for live migration

Original Description:

This adds some common functionality to control QEMU for qemu-iotests.

Additionally, test 085 is updated to use this new functionality.

Some minor fixups along the way, to clear up spaced pathname issues, 
for common.rc, test 019, and test 086.

Jeff Cody (5):
  block: qemu-iotests - add common.qemu, for bash-controlled qemu tests
  block: qemu-iotests - update 085 to use common.qemu
  block: qemu-iotests - test for live migration
  block: qemu-iotests - fix image cleanup when using spaced pathnames
  block: qemu-iotests: make test 019 and 086 work with spaced pathnames

 tests/qemu-iotests/019 |   2 +-
 tests/qemu-iotests/085 |  73 +++
 tests/qemu-iotests/086 |   8 +-
 tests/qemu-iotests/090 |  97 
 tests/qemu-iotests/090.out |  20 +
 tests/qemu-iotests/common.qemu | 195 +
 tests/qemu-iotests/common.rc   |   4 +-
 tests/qemu-iotests/group   |   1 +
 8 files changed, 332 insertions(+), 68 deletions(-)
 create mode 100755 tests/qemu-iotests/090
 create mode 100644 tests/qemu-iotests/090.out
 create mode 100644 tests/qemu-iotests/common.qemu

-- 
1.8.3.1




[Qemu-devel] [PATCH v3 1/5] block: qemu-iotests - add common.qemu, for bash-controlled qemu tests

2014-04-10 Thread Jeff Cody
This creates some common functions for bash language qemu-iotests
to control, and communicate with, a running QEMU process.

4 functions are introduced:

1. _launch_qemu()
This launches the QEMU process(es), and sets up the file
descriptors and fifos for communication.  You can choose to
launch each QEMU process listening for either QMP or HMP
monitor.  You can call this function multiple times, and
save the handle returned from each.  The returned handle is
in $QEMU_HANDLE.  You must copy this value.

Commands 2 and 3 use the handle received from _launch_qemu(), to talk
to the appropriate process.

2. _send_qemu_cmd()
Sends a command string, specified by $2, to QEMU.  If $3 is
non-NULL, _send_qemu_cmd() will wait to receive $3 as a
required result string from QEMU.  Failure to receive $3 will
cause the test to fail.  The command can optionally be retried
$qemu_cmd_repeat number of times.

3. _timed_wait_for()
Waits for a response, for up to a default of 10 seconds.  If
$2 is not seen in that time (anywhere in the response), then
the test fails.  Primarily used by _send_qemu_cmd, but could
be useful standalone, as well.  To prevent automatic exit
(and therefore test failure), set $qemu_wait_no_error to a
non-NULL value.  If $silent is a non-NULL value, then output
to stdout will be suppressed.

4. _cleanup_qemu()
Kills the running QEMU processes, and removes the fifos.

Signed-off-by: Jeff Cody 
---
 tests/qemu-iotests/common.qemu | 195 +
 1 file changed, 195 insertions(+)
 create mode 100644 tests/qemu-iotests/common.qemu

diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
new file mode 100644
index 000..bfa30ba
--- /dev/null
+++ b/tests/qemu-iotests/common.qemu
@@ -0,0 +1,195 @@
+#!/bin/bash
+#
+# This allows for launching of multiple QEMU instances, with independent
+# communication possible to each instance.
+#
+# Each instance can choose, at launch, to use either the QMP or the
+# HMP (monitor) interface.
+#
+# All instances are cleaned up via _cleanup_qemu, including killing the
+# running qemu instance.
+#
+# Copyright (C) 2014 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+QEMU_COMM_TIMEOUT=10
+
+QEMU_FIFO_IN="${TEST_DIR}/qmp-in-$$"
+QEMU_FIFO_OUT="${TEST_DIR}/qmp-out-$$"
+
+QEMU_PID=
+_QEMU_HANDLE=0
+QEMU_HANDLE=0
+
+# If bash version is >= 4.1, these will be overwritten and dynamic
+# file descriptor values assigned.
+_out_fd=3
+_in_fd=4
+
+# Wait for expected QMP response from QEMU.  Will time out
+# after 10 seconds, which counts as failure.
+#
+# Override QEMU_COMM_TIMEOUT for a timeout different than the
+# default 10 seconds
+#
+# $1: The handle to use
+# $2+ All remaining arguments comprise the string to search for
+#in the response.
+#
+# If $silent is set to anything but an empty string, then
+# response is not echoed out.
+function _timed_wait_for()
+{
+local h=${1}
+shift
+
+QEMU_STATUS[$h]=0
+while read -t ${QEMU_COMM_TIMEOUT} resp <&${QEMU_OUT[$h]}
+do
+if [ -z "${silent}" ]; then
+echo "${resp}" | _filter_testdir | _filter_qemu \
+   | _filter_qemu_io | _filter_qmp
+fi
+grep -q "${*}" < <(echo ${resp})
+if [ $? -eq 0 ]; then
+return
+fi
+done
+QEMU_STATUS[$h]=-1
+if [ -z "${qemu_wait_no_error}" ]; then
+echo "Timeout waiting for ${*} on handle ${h}"
+exit 1  # Timeout means the test failed
+fi
+}
+
+
+# Sends QMP or HMP command to QEMU, and waits for the expected response
+#
+# $1:   QEMU handle to use
+# $2:   String of the QMP command to send
+# ${@: -1}  (Last string passed)
+# String that the QEMU response should contain. If it is a null
+# string, do not wait for a response
+#
+# Set qemu_cmd_repeat to the number of times to repeat the cmd
+# until either timeout, or a response.  If it is not set, or <=0,
+# then the command is only sent once.
+#
+function _send_qemu_cmd()
+{
+local h=${1}
+local count=1
+local cmd=
+local use_error=
+shift
+
+if [ ${qemu_cmd_repeat} -gt 0 ] 2>/dev/null; then
+count=${qemu_cmd_repeat}
+use_

Re: [Qemu-devel] [PATCH] Keyboard/Mouse Console for vfio with active function x-vga ans -vga none

2014-04-10 Thread Alex Williamson
On Thu, 2014-04-10 at 22:07 +0200, qemu Mailinglist wrote:
> there are many discus about using keyboard and mouse with VGA passthru,
> so I add a graphic_console to vfio.c, like puv3.c.
> I test it with SDL and VNC Access, the Keyboard works, the mouse work
> good without absolute version like "-usbdevice mouse".
> Default it boot with "QEMU PS/2 Mouse", but this is changing to "vmmouse
> (absolute)" at boot time of gast system.
> 
> I hope someone else can test.
> 
> Signed-off-by: Tobias Nannen q...@suppser.de
> ---
>  hw/misc/vfio.c | 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
> index 9cf5b84..9294041 100644
> --- a/hw/misc/vfio.c
> +++ b/hw/misc/vfio.c
> @@ -39,6 +39,7 @@
>  #include "qemu/range.h"
>  #include "sysemu/kvm.h"
>  #include "sysemu/sysemu.h"
> +#include "ui/console.h"
>  
>  /* #define DEBUG_VFIO */
>  #ifdef DEBUG_VFIO
> @@ -3586,6 +3587,10 @@ static int vfio_get_device(VFIOGroup *group,
> const char *name, VFIODevice *vdev)
>  QLIST_INIT(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].quirks);
>  
>  vdev->has_vga = true;
> +if (vga_interface_type == VGA_NONE) {
> +static const GraphicHwOps no_ops;
> +graphic_console_init(NULL, 0, &no_ops, NULL);
> +}
>  }
>  irq_info.index = VFIO_PCI_ERR_IRQ_INDEX;
>  

I don't think vfio is the one to be creating a dummy console, besides
there's no reason you can't have multiple vfio devices with x-vga=on.
There should probably be some dummy console driver so you can add
-device dummy-console to the commandline if this is desired.  Thanks,

Alex




[Qemu-devel] [PATCH] Keyboard/Mouse Console for vfio with active function x-vga ans -vga none

2014-04-10 Thread qemu Mailinglist
there are many discus about using keyboard and mouse with VGA passthru,
so I add a graphic_console to vfio.c, like puv3.c.
I test it with SDL and VNC Access, the Keyboard works, the mouse work
good without absolute version like "-usbdevice mouse".
Default it boot with "QEMU PS/2 Mouse", but this is changing to "vmmouse
(absolute)" at boot time of gast system.

I hope someone else can test.

Signed-off-by: Tobias Nannen q...@suppser.de
---
 hw/misc/vfio.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index 9cf5b84..9294041 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -39,6 +39,7 @@
 #include "qemu/range.h"
 #include "sysemu/kvm.h"
 #include "sysemu/sysemu.h"
+#include "ui/console.h"
 
 /* #define DEBUG_VFIO */
 #ifdef DEBUG_VFIO
@@ -3586,6 +3587,10 @@ static int vfio_get_device(VFIOGroup *group,
const char *name, VFIODevice *vdev)
 QLIST_INIT(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].quirks);
 
 vdev->has_vga = true;
+if (vga_interface_type == VGA_NONE) {
+static const GraphicHwOps no_ops;
+graphic_console_init(NULL, 0, &no_ops, NULL);
+}
 }
 irq_info.index = VFIO_PCI_ERR_IRQ_INDEX;
 
-- 
1.9.1




Re: [Qemu-devel] [PATCH v4 21/21] hw/arm/virt: Add support for Cortex-A57

2014-04-10 Thread Rob Herring
On Thu, Apr 10, 2014 at 10:02 AM, Peter Maydell
 wrote:
> On 17 March 2014 07:12, Peter Crosthwaite  
> wrote:
>> On Fri, Mar 7, 2014 at 5:33 AM, Peter Maydell  
>> wrote:
>>> Support the Cortex-A57 in the virt machine model.
>>>
>>> Signed-off-by: Peter Maydell 
>>> ---
>>> This should perhaps not be just stealing the a15mpcore_priv
>>> on the basis that it's a GICv2...
>>
>> Wont this mean you gets lots of extraneous hardware? Although, with a
>> pure virtual machine I guess you can do whatever you really want.
>
> No, a15mpcore_priv only has a GIC in it.
>
>>> ---
>>>  hw/arm/virt.c | 8 
>>>  1 file changed, 8 insertions(+)
>>>
>>> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
>>> index 517f2fe..d985d2e 100644
>>> --- a/hw/arm/virt.c
>>> +++ b/hw/arm/virt.c
>>> @@ -123,6 +123,14 @@ static VirtBoardInfo machines[] = {
>>>  .irqmap = a15irqmap,
>>>  },
>>>  {
>>> +.cpu_model = "cortex-a57",
>>> +/* Use the A15 private peripheral model for now: probably wrong! */
>>> +.qdevname = "a15mpcore_priv",
>>
>> Can you just change this to gics qdev name? The qdev propnames of gic
>> and mpcore ("num-cpu" and "num-irq") should just match. Then perhaps a
>> little callback to set gicv2 version property.
>
> That would miss the other thing a15mpcore_priv does for us,
> which is to wire up the generic timer outputs from the CPU
> objects to the appropriate GIC inputs. (Also the gpio_in
> lines on a15mpcore_priv and the gic itself are not the
> same: a15mpcore_priv only exposise the SPIs.)
>
> We could in theory write an a57mpcore_priv which was a
> carbon copy of a15mpcore_priv, but that seems a bit pointless.
> I think it's probably actually reasonable to use a15mpcore_priv
> here, with an appropriate comment:
>
> /* Our A57 has an A15-style GICv2, so we can use a15mpcore_priv */

I think there are 3 possibilities of what actual h/w may look like. i
agree this is the correct thing to do for one case (and is the only
one qemu is able to support today). The others are:

A57 + SBSA compliant GICv2(M)
A57 + GICv3

The SBSA change is making each register bank within the GIC 64K spaced
instead of 4K spaced to support 64KB pages in OSs and hypervisors.
This is a simple address swizzling trick defined in the SBSA doc.
(Since it's documented it must not be a cute embedded nonsense hack.
:)) Then the M portion is for PCI MSI support which is optional.

Rob



[Qemu-devel] [PATCH v3 02/12] check-qdict: Add test for qdict_join()

2014-04-10 Thread Max Reitz
Add some test cases for qdict_join().

Signed-off-by: Max Reitz 
Reviewed-by: Eric Blake 
Reviewed-by: Benoit Canet 
---
 tests/check-qdict.c | 87 +
 1 file changed, 87 insertions(+)

diff --git a/tests/check-qdict.c b/tests/check-qdict.c
index 2ad0f78..a9296f0 100644
--- a/tests/check-qdict.c
+++ b/tests/check-qdict.c
@@ -444,6 +444,92 @@ static void qdict_array_split_test(void)
 QDECREF(test_dict);
 }
 
+static void qdict_join_test(void)
+{
+QDict *dict1, *dict2;
+bool overwrite = false;
+int i;
+
+dict1 = qdict_new();
+dict2 = qdict_new();
+
+
+/* Test everything once without overwrite and once with */
+do
+{
+/* Test empty dicts */
+qdict_join(dict1, dict2, overwrite);
+
+g_assert(qdict_size(dict1) == 0);
+g_assert(qdict_size(dict2) == 0);
+
+
+/* First iteration: Test movement */
+/* Second iteration: Test empty source and non-empty destination */
+qdict_put(dict2, "foo", qint_from_int(42));
+
+for (i = 0; i < 2; i++) {
+qdict_join(dict1, dict2, overwrite);
+
+g_assert(qdict_size(dict1) == 1);
+g_assert(qdict_size(dict2) == 0);
+
+g_assert(qdict_get_int(dict1, "foo") == 42);
+}
+
+
+/* Test non-empty source and destination without conflict */
+qdict_put(dict2, "bar", qint_from_int(23));
+
+qdict_join(dict1, dict2, overwrite);
+
+g_assert(qdict_size(dict1) == 2);
+g_assert(qdict_size(dict2) == 0);
+
+g_assert(qdict_get_int(dict1, "foo") == 42);
+g_assert(qdict_get_int(dict1, "bar") == 23);
+
+
+/* Test conflict */
+qdict_put(dict2, "foo", qint_from_int(84));
+
+qdict_join(dict1, dict2, overwrite);
+
+g_assert(qdict_size(dict1) == 2);
+g_assert(qdict_size(dict2) == !overwrite);
+
+g_assert(qdict_get_int(dict1, "foo") == overwrite ? 84 : 42);
+g_assert(qdict_get_int(dict1, "bar") == 23);
+
+if (!overwrite) {
+g_assert(qdict_get_int(dict2, "foo") == 84);
+}
+
+
+/* Check the references */
+g_assert(qdict_get(dict1, "foo")->refcnt == 1);
+g_assert(qdict_get(dict1, "bar")->refcnt == 1);
+
+if (!overwrite) {
+g_assert(qdict_get(dict2, "foo")->refcnt == 1);
+}
+
+
+/* Clean up */
+qdict_del(dict1, "foo");
+qdict_del(dict1, "bar");
+
+if (!overwrite) {
+qdict_del(dict2, "foo");
+}
+}
+while (overwrite ^= true);
+
+
+QDECREF(dict1);
+QDECREF(dict2);
+}
+
 /*
  * Errors test-cases
  */
@@ -584,6 +670,7 @@ int main(int argc, char **argv)
 g_test_add_func("/public/iterapi", qdict_iterapi_test);
 g_test_add_func("/public/flatten", qdict_flatten_test);
 g_test_add_func("/public/array_split", qdict_array_split_test);
+g_test_add_func("/public/join", qdict_join_test);
 
 g_test_add_func("/errors/put_exists", qdict_put_exists_test);
 g_test_add_func("/errors/get_not_exists", qdict_get_not_exists_test);
-- 
1.9.1




[Qemu-devel] [PATCH v3 00/12] block/json: Add JSON protocol driver

2014-04-10 Thread Max Reitz
This series adds a passthrough JSON protocol block driver. Its filenames
are JSON objects prefixed by "json:". The objects are used as options
for opening another block device which will be the child of the JSON
device. Regarding this child device, the JSON driver behaves nearly the
same as raw_bsd in that it is just a passthrough driver. The only
difference is probably that the JSON driver identifies itself as a block
filter, in contrast to raw_bsd.

The purpose of this driver is that it may sometimes be desirable to
specify options for a block device where only a filename can be given,
e.g., for backing files. Using this should obviously be the exception,
but it is nice to have if actually needed.


v3:
 - rebased on top of Kevin's block branch
 - Patch 5: bdrv_invalidate_cache() now takes an Error parameter, add it
 - Patch 7: Don't use BDRV_BLOCK_RAW, but rather simply pass
   bdrv_get_block_status() to the underlying block device [Benoît/Peter]
 - Patch 12: Test number 084 is already taken, raise it to 089


v2:
 - rebased on top of Kevin's block branch and on Benoît's patch "block:
   Rewrite the snapshot authorization mechanism for block filters."
   (this series now depends on this patch)

 - Added patch 2: Adds test cases for the qdict_join() function
   introduced by patch 1
 - Added patch 3: Since Benoît changed the snapshot authorization
   mechanism, there is now no easy way of detecting whether a block
   filter only has a single child (which is however required for patch
   11). This patch introduces such a way.
 - Patch 4:
   - Simplified return in json_open() [Benoît]
   - Adjusted to fit the new authorization mechanism [Benoît], including
 patch 3 of this series
 - Patch 6: Recursive calls should go to bs->file, not bs itself
   [Benoît]
 - Patch 7: Added missing "*pnum = nb_sectors;" [Benoît]
 - Patch 11: Adjusted to fit the new authorization mechanism [Benoît]
   and especially patch 3
 - Patch 12:
   - Skip test if TEST_IMG contains a quotation mark [Eric]
   - Omit the test number from which two of the test cases are
 originally taken from the test output [Eric]



git-backport-diff against v2:

Key:
[] : patches are identical
[] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively

001/12:[] [--] 'qdict: Add qdict_join()'
002/12:[] [--] 'check-qdict: Add test for qdict_join()'
003/12:[] [--] 'block: Add "has_single_child" field for drivers'
004/12:[] [--] 'block/json: Add JSON protocol driver'
005/12:[0004] [FC] 'block/json: Add functions for cache control'
006/12:[] [-C] 'block/json: Add functions for writing zeroes etc.'
007/12:[0004] [FC] 'block/json: Add bdrv_co_get_block_status()'
008/12:[] [-C] 'block/json: Add ioctl etc.'
009/12:[] [--] 'block/json: Add bdrv_get_specific_info()'
010/12:[] [--] 'block/raw_bsd: Add bdrv_get_specific_info()'
011/12:[] [--] 'block/qapi: Ignore filters on top for format name'
012/12:[0004] [FC] 'iotests: Add test for the JSON protocol'



Max Reitz (12):
  qdict: Add qdict_join()
  check-qdict: Add test for qdict_join()
  block: Add "has_single_child" field for drivers
  block/json: Add JSON protocol driver
  block/json: Add functions for cache control
  block/json: Add functions for writing zeroes etc.
  block/json: Add bdrv_co_get_block_status()
  block/json: Add ioctl etc.
  block/json: Add bdrv_get_specific_info()
  block/raw_bsd: Add bdrv_get_specific_info()
  block/qapi: Ignore filters on top for format name
  iotests: Add test for the JSON protocol

 block.c|   4 +
 block/Makefile.objs|   2 +-
 block/json.c   | 233 +
 block/qapi.c   |  18 +++-
 block/raw_bsd.c|   6 ++
 include/block/block_int.h  |   7 ++
 include/qapi/qmp/qdict.h   |   3 +
 qobject/qdict.c|  32 +++
 tests/check-qdict.c|  87 +
 tests/qemu-iotests/089 | 123 
 tests/qemu-iotests/089.out |  39 
 tests/qemu-iotests/group   |   1 +
 12 files changed, 552 insertions(+), 3 deletions(-)
 create mode 100644 block/json.c
 create mode 100755 tests/qemu-iotests/089
 create mode 100644 tests/qemu-iotests/089.out

-- 
1.9.1




Re: [Qemu-devel] [PATCH v2 2/5] block: qemu-iotests - update 085 to use common.qemu

2014-04-10 Thread Jeff Cody
On Thu, Apr 10, 2014 at 02:10:48PM +0800, Fam Zheng wrote:
> On Wed, 04/09 22:41, Jeff Cody wrote:
> > The new functionality of common.qemu implements the QEMU control
> > and communication functionality that was originally in test 085.
> > 
> > This removes that now-duplicate functionality, and uses the
> > common.qemu functions.
> > 
> 
> Just a note.
> 
> A quick grep shows 067, 071, 081 and 087 are also bash cases with QEMU 
> process.
> Not necessarily in this series but they are also candidates too convert.
>

Good idea - like you said, probably in another series though



[Qemu-devel] [PATCH v3 04/12] block/json: Add JSON protocol driver

2014-04-10 Thread Max Reitz
Add a JSON protocol driver which allows supplying block driver options
through the filename rather than separately. Other than that, it is a
pure passthrough driver which identifies itself as a filter.

This patch implements the functions bdrv_parse_filename(),
bdrv_file_open(), bdrv_close(), bdrv_aio_readv(), bdrv_aio_writev(),
bdrv_getlength(), bdrv_refresh_limits() and bdrv_get_info().

Signed-off-by: Max Reitz 
Reviewed-by: Benoit Canet 
---
 block/Makefile.objs |   2 +-
 block/json.c| 134 
 2 files changed, 135 insertions(+), 1 deletion(-)
 create mode 100644 block/json.c

diff --git a/block/Makefile.objs b/block/Makefile.objs
index fd88c03..d4b70f4 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -5,7 +5,7 @@ block-obj-y += qed-check.o
 block-obj-$(CONFIG_VHDX) += vhdx.o vhdx-endian.o vhdx-log.o
 block-obj-$(CONFIG_QUORUM) += quorum.o
 block-obj-y += parallels.o blkdebug.o blkverify.o
-block-obj-y += snapshot.o qapi.o
+block-obj-y += snapshot.o qapi.o json.o
 block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
 block-obj-$(CONFIG_POSIX) += raw-posix.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
diff --git a/block/json.c b/block/json.c
new file mode 100644
index 000..591bc47
--- /dev/null
+++ b/block/json.c
@@ -0,0 +1,134 @@
+/*
+ * JSON filename wrapper protocol driver
+ *
+ * Copyright (c) 2014 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#include "qemu-common.h"
+#include "block/block_int.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qjson.h"
+
+static void json_parse_filename(const char *filename, QDict *options,
+Error **errp)
+{
+QObject *file_options_obj;
+QDict *full_options;
+
+if (!strstart(filename, "json:", &filename)) {
+error_setg(errp, "Unknown protocol prefix for JSON block driver");
+return;
+}
+
+file_options_obj = qobject_from_json(filename);
+if (!file_options_obj) {
+error_setg(errp, "Could not parse the JSON options");
+return;
+}
+
+if (qobject_type(file_options_obj) != QTYPE_QDICT) {
+qobject_decref(file_options_obj);
+error_setg(errp, "Invalid JSON object");
+return;
+}
+
+full_options = qdict_new();
+qdict_put_obj(full_options, "x-options", file_options_obj);
+qdict_flatten(full_options);
+
+qdict_join(options, full_options, true);
+assert(qdict_size(full_options) == 0);
+QDECREF(full_options);
+}
+
+static int json_open(BlockDriverState *bs, QDict *options, int flags,
+ Error **errp)
+{
+int ret;
+
+assert(bs->file == NULL);
+ret = bdrv_open_image(&bs->file, NULL, options, "x-options", flags, false,
+  errp);
+
+return ret;
+}
+
+static void json_close(BlockDriverState *bs)
+{
+}
+
+static BlockDriverAIOCB *json_aio_readv(BlockDriverState *bs,
+int64_t sector_num, QEMUIOVector *qiov,
+int nb_sectors,
+BlockDriverCompletionFunc *cb,
+void *opaque)
+{
+return bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
+}
+
+static BlockDriverAIOCB *json_aio_writev(BlockDriverState *bs,
+ int64_t sector_num, QEMUIOVector 
*qiov,
+ int nb_sectors,
+ BlockDriverCompletionFunc *cb,
+ void *opaque)
+{
+return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
+}
+
+static int64_t json_getlength(BlockDriverState *bs)
+{
+return bdrv_getlength(bs->file);
+}
+
+static int json_refresh_limits(BlockDriverState *bs)
+{
+bs->bl = bs->file->bl;
+return 0;
+}
+
+static int json_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
+{
+return bdrv_get_info(bs->file, bdi);
+}
+
+static BlockDriver bdrv_json = {
+.format_name= "json",
+.protocol_name  = "json",
+.instance_size  = 0,
+
+.bdrv_parse_filename= json_parse_filename,
+.bdrv_file_open = json_open,
+.bdrv_close = json_close,
+
+.bdrv_aio_readv =

Re: [Qemu-devel] [PATCH for-2.0] qom: Fix crash with qom-list and link properties

2014-04-10 Thread Marcel Apfelbaum
On Thu, 2014-04-10 at 14:47 -0400, Cole Robinson wrote:
> Commit 9561fda8d90e176bef598ba87c42a1bd6ad03ef7 changed the type of
> 'opaque' for link properties, but missed updating this call site.
> Reproducer:
> 
> ./x86_64-softmmu/qemu-system-x86_64 -qmp unix:./qmp.sock,server &
> ./scripts/qmp/qmp-shell ./qmp.sock
> (QEMU) qom-list path=//machine/i440fx/pci.0/child[2]
> 
> Reported-by: Marcin Gibuła 
> Signed-off-by: Cole Robinson 
> ---
>  qom/object.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/qom/object.c b/qom/object.c
> index f4de619..9a730e7 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -1225,7 +1225,8 @@ Object *object_resolve_path_component(Object *parent, 
> const gchar *part)
>  }
>  
>  if (object_property_is_link(prop)) {
> -return *(Object **)prop->opaque;
> +LinkProperty *lprop = prop->opaque;
> +return *lprop->child;

Reviewed-by: Marcel Apfelbaum 

You may want another review from maintainers :), but I think
the fix is fine.

Thanks,
Marcel

>  } else if (object_property_is_child(prop)) {
>  return prop->opaque;
>  } else {






[Qemu-devel] [PATCH v3 03/12] block: Add "has_single_child" field for drivers

2014-04-10 Thread Max Reitz
This field should be used by block drivers acting as filters which have
only a single child BDS which is referenced through the "file" field of
the BDS.

Setting this field allows other block functions to "access" the child
BDS, for instance in bdrv_recurse_is_first_non_filter(). Therefore, it
should not be set if the block layer should not have access to the child
through the filter.

Signed-off-by: Max Reitz 
Reviewed-by: Benoit Canet 
---
 block.c   | 4 
 include/block/block_int.h | 7 +++
 2 files changed, 11 insertions(+)

diff --git a/block.c b/block.c
index 990a754..7662f99 100644
--- a/block.c
+++ b/block.c
@@ -5466,6 +5466,10 @@ bool bdrv_recurse_is_first_non_filter(BlockDriverState 
*bs,
 return bs->drv->bdrv_recurse_is_first_non_filter(bs, candidate);
 }
 
+if (bs->drv->has_single_child) {
+return bdrv_recurse_is_first_non_filter(bs->file, candidate);
+}
+
 /* the driver is a block filter but don't allow to recurse -> return false
  */
 return false;
diff --git a/include/block/block_int.h b/include/block/block_int.h
index cd5bc73..243e974 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -78,6 +78,13 @@ struct BlockDriver {
 
 /* set to true if the BlockDriver is a block filter */
 bool is_filter;
+/* Set to true if the BlockDriver is a filter with a single child 
referenced
+ * through the "file" field in the BDS. This allows the block layer to
+ * access that child through the filter (e.g., for
+ * bdrv_recurse_is_first_non_filter()); if this is not desired, set it to
+ * false (the "file" field should not have been used in this case anyway,
+ * though). */
+bool has_single_child;
 /* for snapshots block filter like Quorum can implement the
  * following recursive callback.
  * It's purpose is to recurse on the filter children while calling
-- 
1.9.1




Re: [Qemu-devel] [PATCH v2 1/5] block: qemu-iotests - add common.qemu, for bash-controlled qemu tests

2014-04-10 Thread Jeff Cody
On Thu, Apr 10, 2014 at 01:27:37PM +0800, Fam Zheng wrote:
> On Wed, 04/09 22:41, Jeff Cody wrote:
> > This creates some common functions for bash language qemu-iotests
> > to control, and communicate with, a running QEMU process.
> > 
> > 4 functions are introduced:
> > 
> > 1. _launch_qemu()
> > This launches the QEMU process(es), and sets up the file
> > descriptors and fifos for communication.  You can choose to
> > launch each QEMU process listening for either QMP or HMP
> > monitor.  You can call this function multiple times, and
> > save the handle returned from each.  The returned handle is
> > in $QEMU_HANDLE.  You must copy this value.
> > 
> > Commands 2 and 3 use the handle received from _launch_qemu(), to talk
> > to the appropriate process.
> > 
> > 2. _send_qemu_cmd()
> > Sends a command string, specified by $2, to QEMU.  If $2 is
> > non-NULL, _send_qemu_cmd() will wait to receive $2 as a
> 
> Do you mean $3 in this sentence?
>

Oops, yes - thanks.

> > required result string from QEMU.  Failure to receive $3 will
> > cause the test to fail.  The command can optionally be retried
> > $qemu_cmd_repeat number of times.
> > 
> > 3. _timed_wait_for()
> > Waits for a response, for up to a default of 10 seconds.  If
> > $2 is not seen in that time (anywhere in the response), then
> > the test fails.  Primarily used by _send_qemu_cmd, but could
> > be useful standalone, as well.  To prevent automatic exit
> > (and therefore test failure), set $qemu_wait_no_error to a
> > non-NULL value.  If $silent is a non-NULL value, then output
> > to stdout will be suppressed.
> > 
> > 4. _cleanup_qemu()
> > Kills the running QEMU processes, and removes the fifos.
> > 
> > Signed-off-by: Jeff Cody 
> > ---
> >  tests/qemu-iotests/common.qemu | 195 
> > +
> >  1 file changed, 195 insertions(+)
> >  create mode 100644 tests/qemu-iotests/common.qemu
> > 
> > diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
> > new file mode 100644
> > index 000..12c42f1
> > --- /dev/null
> > +++ b/tests/qemu-iotests/common.qemu
> > @@ -0,0 +1,195 @@
> > +#!/bin/bash
> > +#
> > +# This allows for launching of multiple QEMU instances, with independent
> > +# communication possible to each instance.
> > +#
> > +# Each instance can choose, at launch, to use either the QMP or the
> > +# HMP (monitor) interface.
> > +#
> > +# All instances are cleaned up via _cleanup_qemu, including killing the
> > +# running qemu instance.
> > +#
> > +# Copyright (C) 2014 Red Hat, Inc.
> > +#
> > +# This program is free software; you can redistribute it and/or modify
> > +# it under the terms of the GNU General Public License as published by
> > +# the Free Software Foundation; either version 2 of the License, or
> > +# (at your option) any later version.
> > +#
> > +# This program is distributed in the hope that it will be useful,
> > +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > +# GNU General Public License for more details.
> > +#
> > +# You should have received a copy of the GNU General Public License
> > +# along with this program.  If not, see .
> > +#
> > +
> > +QEMU_COMM_TIMEOUT=10
> > +
> > +QEMU_FIFO_IN="${TEST_DIR}/qmp-in-$$"
> > +QEMU_FIFO_OUT="${TEST_DIR}/qmp-out-$$"
> > +
> > +QEMU_PID=
> > +_QEMU_HANDLE=0
> > +QEMU_HANDLE=0
> > +
> > +# If bash version is >= 4.1, these will be overwritten and dynamic
> > +# file descriptor values assigned.
> > +_out_fd=3
> > +_in_fd=4
> > +
> > +# Wait for expected QMP response from QEMU.  Will time out
> > +# after 10 seconds, which counts as failure.
> > +#
> > +# Override QEMU_COMM_TIMEOUT for a timeout different than the
> > +# default 10 seconds
> > +#
> > +# $1: The handle to use
> > +# $2+ All remaining arguments comprise the string to search for
> > +#in the response.
> > +#
> > +# If $silent is set to anything but an empty string, then
> > +# response is not echoed out.
> > +function _timed_wait_for()
> > +{
> > +local h=${1}
> > +shift
> > +
> > +QEMU_STATUS[$h]=0
> > +while read -t ${QEMU_COMM_TIMEOUT} resp <&${QEMU_OUT[$h]}
> > +do
> > +if [ -z "${silent}" ]; then
> > +echo "${resp}" | _filter_testdir | _filter_qemu \
> > +   | _filter_qemu_io | _filter_qmp
> > +fi
> > +grep -q "${*}" < <(echo ${resp})
> > +if [ $? -eq 0 ]; then
> > +return
> > +fi
> > +done
> > +QEMU_STATUS[$h]=-1
> > +if [ -z "${qemu_wait_no_error}" ]; then
> > +echo "Timeout waiting for ${*} on handle ${h}"
> > +exit 1  # Timeout means the test failed
> > +fi
> > +}
> > +
> > +
> > +# Sends QMP or HMP command to QEMU, and w

Re: [Qemu-devel] [PATCH V6 1/2] hw/pci: reserve IO and mem for pci-2-pci bridges with no devices attached

2014-04-10 Thread Michael S. Tsirkin
On Thu, Apr 10, 2014 at 09:55:21PM +0300, Marcel Apfelbaum wrote:
> If a pci-2-pci bridge supports hot-plug functionality but there are no devices
> connected to it, reserve IO/mem in order to be able to attach devices
> later. Do not waste space, use minimum allowed.
> 
> Reviewed-by: Michael S. Tsirkin 
> Signed-off-by: Marcel Apfelbaum 

Acked-by: Michael S. Tsirkin 

> ---
>  src/fw/pciinit.c |  3 +++
>  src/hw/pci.c | 19 +++
>  src/hw/pci.h |  1 +
>  3 files changed, 23 insertions(+)
> 
> diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
> index 64f1d41..9b5d7ad 100644
> --- a/src/fw/pciinit.c
> +++ b/src/fw/pciinit.c
> @@ -677,12 +677,15 @@ static int pci_bios_check_devices(struct pci_bus 
> *busses)
>  continue;
>  struct pci_bus *parent = &busses[pci_bdf_to_bus(s->bus_dev->bdf)];
>  int type;
> +u8 shpc_cap = pci_find_capability(s->bus_dev, PCI_CAP_ID_SHPC);
>  for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
>  u64 align = (type == PCI_REGION_TYPE_IO) ?
>  PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
>  if (pci_region_align(&s->r[type]) > align)
>   align = pci_region_align(&s->r[type]);
>  u64 sum = pci_region_sum(&s->r[type]);
> +if (!sum && shpc_cap)
> +sum = align; /* reserve min size for hot-plug */
>  u64 size = ALIGN(sum, align);
>  int is64 = pci_bios_bridge_region_is64(&s->r[type],
>  s->bus_dev, type);
> diff --git a/src/hw/pci.c b/src/hw/pci.c
> index caf9265..77cdba2 100644
> --- a/src/hw/pci.c
> +++ b/src/hw/pci.c
> @@ -225,6 +225,25 @@ pci_find_init_device(const struct pci_device_id *ids, 
> void *arg)
>  return NULL;
>  }
>  
> +u8 pci_find_capability(struct pci_device *pci, u8 cap_id)
> +{
> +int i;
> +u8 cap;
> +u16 status = pci_config_readw(pci->bdf, PCI_STATUS);
> +
> +if (!(status & PCI_STATUS_CAP_LIST))
> +return 0;
> +
> +cap = pci_config_readb(pci->bdf, PCI_CAPABILITY_LIST);
> +for (i = 0; cap && i <= 0xff; i++) {
> +if (pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_ID) == cap_id)
> +return cap;
> +cap = pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_NEXT);
> +}
> +
> +return 0;
> +}
> +
>  void
>  pci_reboot(void)
>  {
> diff --git a/src/hw/pci.h b/src/hw/pci.h
> index 167a027..e828225 100644
> --- a/src/hw/pci.h
> +++ b/src/hw/pci.h
> @@ -116,6 +116,7 @@ int pci_init_device(const struct pci_device_id *ids
>  , struct pci_device *pci, void *arg);
>  struct pci_device *pci_find_init_device(const struct pci_device_id *ids
>  , void *arg);
> +u8 pci_find_capability(struct pci_device *pci, u8 cap_id);
>  void pci_reboot(void);
>  
>  #endif
> -- 
> 1.8.3.1



Re: [Qemu-devel] [PATCH V6 2/2] hw/pci: check if pci2pci bridges implement optional limit registers

2014-04-10 Thread Michael S. Tsirkin
On Thu, Apr 10, 2014 at 09:55:22PM +0300, Marcel Apfelbaum wrote:
>  pair and
>  pair
> are both optional.
> Do not reserve ranges if the above registers are not implemented.
> 
> Signed-off-by: Marcel Apfelbaum 


Acked-by: Michael S. Tsirkin 

> ---
>  src/fw/pciinit.c |  9 ++---
>  src/hw/pci.c | 26 ++
>  src/hw/pci.h |  9 +
>  3 files changed, 37 insertions(+), 7 deletions(-)
> 
> diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
> index 9b5d7ad..bbaecd6 100644
> --- a/src/fw/pciinit.c
> +++ b/src/fw/pciinit.c
> @@ -26,13 +26,6 @@
>  #define PCI_BRIDGE_MEM_MIN(1<<21)  // 2M == hugepage size
>  #define PCI_BRIDGE_IO_MIN  0x1000  // mandated by pci bridge spec
>  
> -enum pci_region_type {
> -PCI_REGION_TYPE_IO,
> -PCI_REGION_TYPE_MEM,
> -PCI_REGION_TYPE_PREFMEM,
> -PCI_REGION_TYPE_COUNT,
> -};
> -
>  static const char *region_type_name[] = {
>  [ PCI_REGION_TYPE_IO ]  = "io",
>  [ PCI_REGION_TYPE_MEM ] = "mem",
> @@ -681,6 +674,8 @@ static int pci_bios_check_devices(struct pci_bus *busses)
>  for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
>  u64 align = (type == PCI_REGION_TYPE_IO) ?
>  PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
> +if (!pci_bridge_has_region(s->bus_dev, type))
> +continue;
>  if (pci_region_align(&s->r[type]) > align)
>   align = pci_region_align(&s->r[type]);
>  u64 sum = pci_region_sum(&s->r[type]);
> diff --git a/src/hw/pci.c b/src/hw/pci.c
> index 77cdba2..390b4dd 100644
> --- a/src/hw/pci.c
> +++ b/src/hw/pci.c
> @@ -244,6 +244,32 @@ u8 pci_find_capability(struct pci_device *pci, u8 cap_id)
>  return 0;
>  }
>  
> +/* Test whether bridge support forwarding of transactions
> + * of a specific type.
> + * Note: disables bridge's window registers as a side effect.
> + */
> +int pci_bridge_has_region(struct pci_device *pci,
> +enum pci_region_type region_type)
> +{
> +u8 base;
> +
> +switch (region_type) {
> +case PCI_REGION_TYPE_IO:
> +base = PCI_IO_BASE;
> +break;
> +case PCI_REGION_TYPE_PREFMEM:
> +base = PCI_PREF_MEMORY_BASE;
> +break;
> +default:
> +/* Regular memory support is mandatory */
> +return 1;
> +}
> +
> +pci_config_writeb(pci->bdf, base, 0xFF);
> +
> +return pci_config_readb(pci->bdf, base) != 0;
> +}
> +
>  void
>  pci_reboot(void)
>  {
> diff --git a/src/hw/pci.h b/src/hw/pci.h
> index e828225..0aaa84c 100644
> --- a/src/hw/pci.h
> +++ b/src/hw/pci.h
> @@ -12,6 +12,13 @@
>  #define PCI_NUM_REGIONS 7
>  #define PCI_BRIDGE_NUM_REGIONS 2
>  
> +enum pci_region_type {
> +PCI_REGION_TYPE_IO,
> +PCI_REGION_TYPE_MEM,
> +PCI_REGION_TYPE_PREFMEM,
> +PCI_REGION_TYPE_COUNT,
> +};
> +
>  static inline u8 pci_bdf_to_bus(u16 bdf) {
>  return bdf >> 8;
>  }
> @@ -117,6 +124,8 @@ int pci_init_device(const struct pci_device_id *ids
>  struct pci_device *pci_find_init_device(const struct pci_device_id *ids
>  , void *arg);
>  u8 pci_find_capability(struct pci_device *pci, u8 cap_id);
> +int pci_bridge_has_region(struct pci_device *pci,
> +  enum pci_region_type region_type);
>  void pci_reboot(void);
>  
>  #endif
> -- 
> 1.8.3.1



[Qemu-devel] [PATCH v3 01/12] qdict: Add qdict_join()

2014-04-10 Thread Max Reitz
This function joins two QDicts by absorbing one into the other.

Signed-off-by: Max Reitz 
Reviewed-by: Benoit Canet 
Reviewed-by: Eric Blake 
---
 include/qapi/qmp/qdict.h |  3 +++
 qobject/qdict.c  | 32 
 2 files changed, 35 insertions(+)

diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index 1ddf97b..d68f4eb 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -16,6 +16,7 @@
 #include "qapi/qmp/qobject.h"
 #include "qapi/qmp/qlist.h"
 #include "qemu/queue.h"
+#include 
 #include 
 
 #define QDICT_BUCKET_MAX 512
@@ -70,4 +71,6 @@ void qdict_flatten(QDict *qdict);
 void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start);
 void qdict_array_split(QDict *src, QList **dst);
 
+void qdict_join(QDict *dest, QDict *src, bool overwrite);
+
 #endif /* QDICT_H */
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 42ec4c0..ea239f0 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -665,3 +665,35 @@ void qdict_array_split(QDict *src, QList **dst)
 qlist_append_obj(*dst, subqobj ?: QOBJECT(subqdict));
 }
 }
+
+/**
+ * qdict_join(): Absorb the src QDict into the dest QDict, that is, move all
+ * elements from src to dest.
+ *
+ * If an element from src has a key already present in dest, it will not be
+ * moved unless overwrite is true.
+ *
+ * If overwrite is true, the conflicting values in dest will be discarded and
+ * replaced by the corresponding values from src.
+ *
+ * Therefore, with overwrite being true, the src QDict will always be empty 
when
+ * this function returns. If overwrite is false, the src QDict will be empty
+ * iff there were no conflicts.
+ */
+void qdict_join(QDict *dest, QDict *src, bool overwrite)
+{
+const QDictEntry *entry, *next;
+
+entry = qdict_first(src);
+while (entry) {
+next = qdict_next(src, entry);
+
+if (overwrite || !qdict_haskey(dest, entry->key)) {
+qobject_incref(entry->value);
+qdict_put_obj(dest, entry->key, entry->value);
+qdict_del(src, entry->key);
+}
+
+entry = next;
+}
+}
-- 
1.9.1




Re: [Qemu-devel] [PATCH v3 07/12] block/json: Add bdrv_co_get_block_status()

2014-04-10 Thread Max Reitz

On 10.04.2014 20:58, Benoît Canet wrote:

The Thursday 10 Apr 2014 à 20:43:38 (+0200), Max Reitz wrote :

Implement this function by passing it through to bs->file.

Signed-off-by: Max Reitz 
---
  block/json.c | 8 
  1 file changed, 8 insertions(+)

diff --git a/block/json.c b/block/json.c
index cb83780..dfeec81 100644
--- a/block/json.c
+++ b/block/json.c
@@ -110,6 +110,13 @@ static coroutine_fn int 
json_co_write_zeroes(BlockDriverState *bs,
  return bdrv_co_write_zeroes(bs->file, sector_num, nb_sectors, flags);
  }
  
+static coroutine_fn int64_t json_co_get_block_status(BlockDriverState *bs,

+ int64_t sector_num,
+ int nb_sectors, int *pnum)
+{
+return bdrv_get_block_status(bs->file, sector_num, nb_sectors, pnum);
+}
+
  static void json_invalidate_cache(BlockDriverState *bs, Error **errp)
  {
  return bdrv_invalidate_cache(bs->file, errp);
@@ -156,6 +163,7 @@ static BlockDriver bdrv_json = {
  .bdrv_aio_discard   = json_aio_discard,
  
  .bdrv_co_write_zeroes   = json_co_write_zeroes,

+.bdrv_co_get_block_status   = json_co_get_block_status,
  
  .bdrv_invalidate_cache  = json_invalidate_cache,
  
--

1.9.1


Reviewed-by: Benoit Canet 

Here you go :)


Thank you :D



Re: [Qemu-devel] [PATCH v3 07/12] block/json: Add bdrv_co_get_block_status()

2014-04-10 Thread Benoît Canet
The Thursday 10 Apr 2014 à 20:43:38 (+0200), Max Reitz wrote :
> Implement this function by passing it through to bs->file.
> 
> Signed-off-by: Max Reitz 
> ---
>  block/json.c | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/block/json.c b/block/json.c
> index cb83780..dfeec81 100644
> --- a/block/json.c
> +++ b/block/json.c
> @@ -110,6 +110,13 @@ static coroutine_fn int 
> json_co_write_zeroes(BlockDriverState *bs,
>  return bdrv_co_write_zeroes(bs->file, sector_num, nb_sectors, flags);
>  }
>  
> +static coroutine_fn int64_t json_co_get_block_status(BlockDriverState *bs,
> + int64_t sector_num,
> + int nb_sectors, int 
> *pnum)
> +{
> +return bdrv_get_block_status(bs->file, sector_num, nb_sectors, pnum);
> +}
> +
>  static void json_invalidate_cache(BlockDriverState *bs, Error **errp)
>  {
>  return bdrv_invalidate_cache(bs->file, errp);
> @@ -156,6 +163,7 @@ static BlockDriver bdrv_json = {
>  .bdrv_aio_discard   = json_aio_discard,
>  
>  .bdrv_co_write_zeroes   = json_co_write_zeroes,
> +.bdrv_co_get_block_status   = json_co_get_block_status,
>  
>  .bdrv_invalidate_cache  = json_invalidate_cache,
>  
> -- 
> 1.9.1
> 
Reviewed-by: Benoit Canet 

Here you go :)



Re: [Qemu-devel] [PATCH v3 05/12] block/json: Add functions for cache control

2014-04-10 Thread Benoît Canet
The Thursday 10 Apr 2014 à 20:43:36 (+0200), Max Reitz wrote :
> Add passthrough functions for bdrv_aio_flush() and
> bdrv_invalidate_cache().
> 
> Signed-off-by: Max Reitz 
> ---
>  block/json.c | 15 +++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/block/json.c b/block/json.c
> index 591bc47..0e2d518 100644
> --- a/block/json.c
> +++ b/block/json.c
> @@ -88,6 +88,18 @@ static BlockDriverAIOCB *json_aio_writev(BlockDriverState 
> *bs,
>  return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, 
> opaque);
>  }
>  
> +static BlockDriverAIOCB *json_aio_flush(BlockDriverState *bs,
> +BlockDriverCompletionFunc *cb,
> +void *opaque)
> +{
> +return bdrv_aio_flush(bs->file, cb, opaque);
> +}
> +
> +static void json_invalidate_cache(BlockDriverState *bs, Error **errp)
> +{
> +return bdrv_invalidate_cache(bs->file, errp);
> +}
> +
>  static int64_t json_getlength(BlockDriverState *bs)
>  {
>  return bdrv_getlength(bs->file);
> @@ -115,6 +127,9 @@ static BlockDriver bdrv_json = {
>  
>  .bdrv_aio_readv = json_aio_readv,
>  .bdrv_aio_writev= json_aio_writev,
> +.bdrv_aio_flush = json_aio_flush,
> +
> +.bdrv_invalidate_cache  = json_invalidate_cache,
>  
>  .has_variable_length= true,
>  .bdrv_getlength = json_getlength,
> -- 
> 1.9.1
> 
Reviewed-by: Benoit Canet 




Re: [Qemu-devel] Should we have a 2.0-rc3 ?

2014-04-10 Thread Cole Robinson
On 04/10/2014 07:17 AM, Peter Maydell wrote:
> So far I know of at least three fixes which should probably
> go into 2.0:
>  * my fix for the configure stack-protector checks on MacOSX
>  * MST's pull request updating the ACPI test blobs
>  * MST says we need to update the hex files for ACPI too
>(otherwise you get a different ACPI blob depending on whether
> your build system had iasl or not, if I understand correctly)
> 
> Are there any others?
> 

https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg00217.html

Relative mode with sdl2.c is completely busted. Patch 1 is safe and makes the
mouse actually move, but with the cruddy 'invisible wall' behavior. Patch 2
fixes that, but I haven't tested it enough to know if there are side effects.

Gerd, can you take a look at patch #1 and consider sending a 2.0 pull request?

Thanks,
Cole




[Qemu-devel] [PATCH V6 2/2] hw/pci: check if pci2pci bridges implement optional limit registers

2014-04-10 Thread Marcel Apfelbaum
 pair and
 pair
are both optional.
Do not reserve ranges if the above registers are not implemented.

Signed-off-by: Marcel Apfelbaum 
---
 src/fw/pciinit.c |  9 ++---
 src/hw/pci.c | 26 ++
 src/hw/pci.h |  9 +
 3 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
index 9b5d7ad..bbaecd6 100644
--- a/src/fw/pciinit.c
+++ b/src/fw/pciinit.c
@@ -26,13 +26,6 @@
 #define PCI_BRIDGE_MEM_MIN(1<<21)  // 2M == hugepage size
 #define PCI_BRIDGE_IO_MIN  0x1000  // mandated by pci bridge spec
 
-enum pci_region_type {
-PCI_REGION_TYPE_IO,
-PCI_REGION_TYPE_MEM,
-PCI_REGION_TYPE_PREFMEM,
-PCI_REGION_TYPE_COUNT,
-};
-
 static const char *region_type_name[] = {
 [ PCI_REGION_TYPE_IO ]  = "io",
 [ PCI_REGION_TYPE_MEM ] = "mem",
@@ -681,6 +674,8 @@ static int pci_bios_check_devices(struct pci_bus *busses)
 for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
 u64 align = (type == PCI_REGION_TYPE_IO) ?
 PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
+if (!pci_bridge_has_region(s->bus_dev, type))
+continue;
 if (pci_region_align(&s->r[type]) > align)
  align = pci_region_align(&s->r[type]);
 u64 sum = pci_region_sum(&s->r[type]);
diff --git a/src/hw/pci.c b/src/hw/pci.c
index 77cdba2..390b4dd 100644
--- a/src/hw/pci.c
+++ b/src/hw/pci.c
@@ -244,6 +244,32 @@ u8 pci_find_capability(struct pci_device *pci, u8 cap_id)
 return 0;
 }
 
+/* Test whether bridge support forwarding of transactions
+ * of a specific type.
+ * Note: disables bridge's window registers as a side effect.
+ */
+int pci_bridge_has_region(struct pci_device *pci,
+enum pci_region_type region_type)
+{
+u8 base;
+
+switch (region_type) {
+case PCI_REGION_TYPE_IO:
+base = PCI_IO_BASE;
+break;
+case PCI_REGION_TYPE_PREFMEM:
+base = PCI_PREF_MEMORY_BASE;
+break;
+default:
+/* Regular memory support is mandatory */
+return 1;
+}
+
+pci_config_writeb(pci->bdf, base, 0xFF);
+
+return pci_config_readb(pci->bdf, base) != 0;
+}
+
 void
 pci_reboot(void)
 {
diff --git a/src/hw/pci.h b/src/hw/pci.h
index e828225..0aaa84c 100644
--- a/src/hw/pci.h
+++ b/src/hw/pci.h
@@ -12,6 +12,13 @@
 #define PCI_NUM_REGIONS 7
 #define PCI_BRIDGE_NUM_REGIONS 2
 
+enum pci_region_type {
+PCI_REGION_TYPE_IO,
+PCI_REGION_TYPE_MEM,
+PCI_REGION_TYPE_PREFMEM,
+PCI_REGION_TYPE_COUNT,
+};
+
 static inline u8 pci_bdf_to_bus(u16 bdf) {
 return bdf >> 8;
 }
@@ -117,6 +124,8 @@ int pci_init_device(const struct pci_device_id *ids
 struct pci_device *pci_find_init_device(const struct pci_device_id *ids
 , void *arg);
 u8 pci_find_capability(struct pci_device *pci, u8 cap_id);
+int pci_bridge_has_region(struct pci_device *pci,
+  enum pci_region_type region_type);
 void pci_reboot(void);
 
 #endif
-- 
1.8.3.1




[Qemu-devel] [PATCH V6 0/2] hw/pci: reserve IO and mem for pci-2-pci bridges with no devices attached

2014-04-10 Thread Marcel Apfelbaum
v5 -> v6:
 - Minor, fixed a typo in the subject

v4 -> v5
 - Addressed Michael S. Tsirkin's comments (patch 2/2):
   - Open-coded pci_config_is_reserved() method.

v3 -> v4:
 - Addressed Kevin O'Connor's comments:
   - Refactored a for loop in patch 1/2.
 - Addressed Michael S. Tsirkin's comments (patch 2/2):
   - Removed not needed method
   - Test only base registers (dropped limits tests)
   - Renamed a helper method
   - Used 0xFF to test if the memory is reserved
   - Simplified code in pci_bridge_has_region
 - I did keep the code that restores base's address as I don't want
   to modify the registers in a 'query' method. (as replied on the mail thread)

v2 -> v3:
 - Addressed Michael S. Tsirkin's comments:
   - I/O and Prefetchable Memory are optional. Do not allocate ranges
 if they are not implemented (2/2).
 - Note that 2/2 patch can be seen as a separate fix. However, it
   is related to ranges reservation.

v1 -> v2:
 - Thanks Gerd Hoffmann for the review.
 - Addressed Michael S. Tsirkin's comments:
   - Limit capabilities query to 256 iterations, to make sure we
 don't get into an infinite loop with a broken device.


If a pci-2-pci bridge supports hot-plug functionality but there are no devices
connected to it, reserve IO/mem in order to be able to attach devices
later. Do not waste space, use minimum allowed.

Marcel Apfelbaum (2):
  hw/pci: reserve IO and mem for pci-2-pci bridges with no devices
attached
  hw/pci: check if pci2pci bridges implement optional limit registers

 src/fw/pciinit.c | 12 +---
 src/hw/pci.c | 45 +
 src/hw/pci.h | 10 ++
 3 files changed, 60 insertions(+), 7 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH V6 1/2] hw/pci: reserve IO and mem for pci-2-pci bridges with no devices attached

2014-04-10 Thread Marcel Apfelbaum
If a pci-2-pci bridge supports hot-plug functionality but there are no devices
connected to it, reserve IO/mem in order to be able to attach devices
later. Do not waste space, use minimum allowed.

Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Marcel Apfelbaum 
---
 src/fw/pciinit.c |  3 +++
 src/hw/pci.c | 19 +++
 src/hw/pci.h |  1 +
 3 files changed, 23 insertions(+)

diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
index 64f1d41..9b5d7ad 100644
--- a/src/fw/pciinit.c
+++ b/src/fw/pciinit.c
@@ -677,12 +677,15 @@ static int pci_bios_check_devices(struct pci_bus *busses)
 continue;
 struct pci_bus *parent = &busses[pci_bdf_to_bus(s->bus_dev->bdf)];
 int type;
+u8 shpc_cap = pci_find_capability(s->bus_dev, PCI_CAP_ID_SHPC);
 for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
 u64 align = (type == PCI_REGION_TYPE_IO) ?
 PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
 if (pci_region_align(&s->r[type]) > align)
  align = pci_region_align(&s->r[type]);
 u64 sum = pci_region_sum(&s->r[type]);
+if (!sum && shpc_cap)
+sum = align; /* reserve min size for hot-plug */
 u64 size = ALIGN(sum, align);
 int is64 = pci_bios_bridge_region_is64(&s->r[type],
 s->bus_dev, type);
diff --git a/src/hw/pci.c b/src/hw/pci.c
index caf9265..77cdba2 100644
--- a/src/hw/pci.c
+++ b/src/hw/pci.c
@@ -225,6 +225,25 @@ pci_find_init_device(const struct pci_device_id *ids, void 
*arg)
 return NULL;
 }
 
+u8 pci_find_capability(struct pci_device *pci, u8 cap_id)
+{
+int i;
+u8 cap;
+u16 status = pci_config_readw(pci->bdf, PCI_STATUS);
+
+if (!(status & PCI_STATUS_CAP_LIST))
+return 0;
+
+cap = pci_config_readb(pci->bdf, PCI_CAPABILITY_LIST);
+for (i = 0; cap && i <= 0xff; i++) {
+if (pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_ID) == cap_id)
+return cap;
+cap = pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_NEXT);
+}
+
+return 0;
+}
+
 void
 pci_reboot(void)
 {
diff --git a/src/hw/pci.h b/src/hw/pci.h
index 167a027..e828225 100644
--- a/src/hw/pci.h
+++ b/src/hw/pci.h
@@ -116,6 +116,7 @@ int pci_init_device(const struct pci_device_id *ids
 , struct pci_device *pci, void *arg);
 struct pci_device *pci_find_init_device(const struct pci_device_id *ids
 , void *arg);
+u8 pci_find_capability(struct pci_device *pci, u8 cap_id);
 void pci_reboot(void);
 
 #endif
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 12/12] iotests: Add test for the JSON protocol

2014-04-10 Thread Max Reitz
Add a test for the JSON protocol driver.

Signed-off-by: Max Reitz 
Reviewed-by: Benoit Canet 
---
 tests/qemu-iotests/089 | 123 +
 tests/qemu-iotests/089.out |  39 ++
 tests/qemu-iotests/group   |   1 +
 3 files changed, 163 insertions(+)
 create mode 100755 tests/qemu-iotests/089
 create mode 100644 tests/qemu-iotests/089.out

diff --git a/tests/qemu-iotests/089 b/tests/qemu-iotests/089
new file mode 100755
index 000..75cb0c2
--- /dev/null
+++ b/tests/qemu-iotests/089
@@ -0,0 +1,123 @@
+#!/bin/bash
+#
+# Test case for the JSON block protocol
+#
+# Copyright (C) 2014 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+# creator
+owner=mre...@redhat.com
+
+seq="$(basename $0)"
+echo "QA output created by $seq"
+
+here="$PWD"
+tmp=/tmp/$$
+status=1   # failure is the default!
+
+_cleanup()
+{
+   _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+
+# Using an image filename containing quotation marks will render the JSON data
+# below invalid. In that case, we have little choice but simply not to run this
+# test.
+case $TEST_IMG in
+*'"'*)
+_notrun "image filename may not contain quotation marks"
+;;
+esac
+
+IMG_SIZE=64M
+
+# Taken from test 072
+echo
+echo "=== Testing nested image formats ==="
+echo
+
+TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE
+
+$QEMU_IO -c 'write -P 42 0 512' -c 'write -P 23 512 512' \
+ -c 'write -P 66 1024 512' "$TEST_IMG.base" | _filter_qemu_io
+
+$QEMU_IMG convert -f raw -O $IMGFMT "$TEST_IMG.base" "$TEST_IMG"
+
+$QEMU_IO -c 'read -P 42 0 512' -c 'read -P 23 512 512' \
+ -c 'read -P 66 1024 512' "json:{
+\"driver\": \"$IMGFMT\",
+\"file\": {
+\"driver\": \"$IMGFMT\",
+\"file\": {
+\"filename\": \"$TEST_IMG\"
+}
+}
+}" | _filter_qemu_io
+
+# This should fail (see test 072)
+$QEMU_IO -c 'read -P 42 0 512' "$TEST_IMG" | _filter_qemu_io
+
+
+# Taken from test 071
+echo
+echo "=== Testing blkdebug ==="
+echo
+
+_make_test_img $IMG_SIZE
+
+$QEMU_IO -c 'write -P 42 0x38000 512' "$TEST_IMG" | _filter_qemu_io
+
+# The "image.filename" part tests whether "a": { "b": "c" } and "a.b": "c" do
+# the same (which they should).
+# This has to use -g to force qemu-io to use BDRV_O_PROTOCOL, since it will try
+# to determine the format of the file otherwise; due to the complexity of the
+# filename, only raw (or json itself) will work and this will then result in an
+# error because of the blkdebug part. Thus, use -g.
+$QEMU_IO -c 'read -P 42 0x38000 512' -g "json:{
+\"driver\": \"$IMGFMT\",
+\"file\": {
+\"driver\": \"blkdebug\",
+\"inject-error\": [{
+\"event\": \"l2_load\"
+}],
+\"image.filename\": \"$TEST_IMG\"
+}
+}" | _filter_qemu_io
+
+
+echo
+echo "=== Testing qemu-img info output ==="
+echo
+
+# This should output information about the image itself, not about the JSON
+# block device.
+$QEMU_IMG info "json:{\"driver\":\"qcow2\",\"file.filename\":\"$TEST_IMG\"}" \
+| _filter_testdir | _filter_imgfmt
+
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/089.out b/tests/qemu-iotests/089.out
new file mode 100644
index 000..4804ff0
--- /dev/null
+++ b/tests/qemu-iotests/089.out
@@ -0,0 +1,39 @@
+QA output created by 089
+
+=== Testing nested image formats ===
+
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 
+wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 512/512 bytes at offset 512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 512/512 bytes at offset 1024
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 1024
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Pattern verification failed at offset 0, 512 bytes
+read 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Testing blkdebug ===
+
+Format

Re: [Qemu-devel] qemu 2.0.0-rc2 crash

2014-04-10 Thread Marcel Apfelbaum
On Thu, 2014-04-10 at 14:38 -0400, Cole Robinson wrote:
> On 04/10/2014 02:15 PM, Cole Robinson wrote:
> > On 04/10/2014 12:39 PM, Marcel Apfelbaum wrote:
> >> On Thu, 2014-04-10 at 18:24 +0200, Marcin Gibuła wrote:
> >>> W dniu 2014-04-10 15:43, Marcel Apfelbaum pisze:
>  On Thu, 2014-04-10 at 14:55 +0200, Marcin Gibuła wrote:
> > Hi,
> >
> > I've been playing with QEMU 2.0-rc2 and found a crash that isn't there
> > in 1.7.1.
>  Hi Marcin,
>  Thanks for reporting the bug!
> 
>  Do you have a development environment?
>  If you do, and the reproduction is fast (and you already have a setup),
>  a git bisect to find the problematic commit would be appreciated,
> >>>
> >>> Hi,
> >>>
> >>> yes, it's on development environment. If you could point me to some 
> >>> quick guide to bisecting qemu, I'll be happy to do it.
> >>
> >> Sure! Thanks for helping.
> >>
> >> 1. Start:
> >>  git bisect start
> >>  git bisect good  
> >> (Ex: v1.7.1)
> >>  git bisect bad  
> >> (Ex: HEAD)
> >> 2. Git will checkout commits for you and you have to check and answer:
> >>  git bisect good or git bisect bad 
> >> 3. Git will show you the first bad commit.
> >>
> >> A more detailed version here:
> >> http://git-scm.com/book/en/Git-Tools-Debugging-with-Git
> >> Look for git-bisect.
> > 
> > Actually I was just independently bisecting this :) Culprit is:
> > 
> > commit 9561fda8d90e176bef598ba87c42a1bd6ad03ef7
> > Author: Stefan Hajnoczi 
> > Date:   Wed Mar 19 08:58:55 2014 +0100
> > 
> > qom: Make QOM link property unref optional
> > 
> > Simple reproducer:
> > 
> > ./x86_64-softmmu/qemu-system-x86_64 -qmp unix:./qmp.sock,server
> > 
> > ./scripts/qmp/qmp-shell ./qmp.sock
> > (QEMU) qom-list path=//machine/i440fx/pci.0/child[2]
> > 
> > Seems like trying to qom-list any link property will crash
> > 
> 
> I think this is the fix:
> 
> diff --git a/qom/object.c b/qom/object.c
> index f4de619..9a730e7 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -1225,7 +1225,8 @@ Object *object_resolve_path_component(Object *parent, 
> cons
>  }
> 
>  if (object_property_is_link(prop)) {
> -return *(Object **)prop->opaque;
> +LinkProperty *lprop = prop->opaque;
> +return *lprop->child;
Seems OK to me, but I am not so familiar with this part...
maybe we'll get a feedback from the maintainers.

Thanks,
Marcel

>  } else if (object_property_is_child(prop)) {
>  return prop->opaque;
>  } else {
> 
> The commit mentioned above changed the type of opaque for link properties, but
> forgot to update this site. I'll send a top level patch.
> 
> - Cole
> 






[Qemu-devel] [PATCH v3 10/12] block/raw_bsd: Add bdrv_get_specific_info()

2014-04-10 Thread Max Reitz
Add a passthrough function for bdrv_get_specific_info().

Signed-off-by: Max Reitz 
Reviewed-by: Benoit Canet 
---
 block/raw_bsd.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 01ea692..e93ccd3 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -90,6 +90,11 @@ static int raw_get_info(BlockDriverState *bs, 
BlockDriverInfo *bdi)
 return bdrv_get_info(bs->file, bdi);
 }
 
+static ImageInfoSpecific *raw_get_specific_info(BlockDriverState *bs)
+{
+return bdrv_get_specific_info(bs->file);
+}
+
 static int raw_refresh_limits(BlockDriverState *bs)
 {
 bs->bl = bs->file->bl;
@@ -187,6 +192,7 @@ static BlockDriver bdrv_raw = {
 .bdrv_getlength   = &raw_getlength,
 .has_variable_length  = true,
 .bdrv_get_info= &raw_get_info,
+.bdrv_get_specific_info = &raw_get_specific_info,
 .bdrv_refresh_limits  = &raw_refresh_limits,
 .bdrv_is_inserted = &raw_is_inserted,
 .bdrv_media_changed   = &raw_media_changed,
-- 
1.9.1




[Qemu-devel] [PATCH v3 11/12] block/qapi: Ignore filters on top for format name

2014-04-10 Thread Max Reitz
bdrv_query_image_info() currently deduces the image filename and the
format name from the top BDS. However, it is probably more reasonable to
ignore as many filters as possible on top of the BDS chain since those
neither change the type nor the filename of the underlying image.

Filters like quorum which have multiple underlying BDS should not be
removed, however, since the underlying BDS chains may lead to different
image formats and most certainly to different filenames. Therefore, only
simple filters with a single underlying BDS may be skipped.

In addition, any "raw" BDS on top of such a simple filter should be
removed, since they have probably been automatically created by
bdrv_open() but basically function as a simple filter as well.

Signed-off-by: Max Reitz 
Reviewed-by: Benoit Canet 
---
 block/qapi.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index 8f2b4db..84b3097 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -171,11 +171,25 @@ void bdrv_query_image_info(BlockDriverState *bs,
 int ret;
 Error *err = NULL;
 ImageInfo *info = g_new0(ImageInfo, 1);
+BlockDriverState *ubs;
 
 bdrv_get_geometry(bs, &total_sectors);
 
-info->filename= g_strdup(bs->filename);
-info->format  = g_strdup(bdrv_get_format_name(bs));
+/* Remove the top layer of filters; that is, remove every "raw" BDS on top
+ * of a single-child filter and every single-child filter itself until a 
BDS
+ * is encountered which cannot be removed through these rules */
+ubs = bs;
+while ((ubs->drv && ubs->drv->is_filter && ubs->drv->has_single_child) ||
+   (ubs->drv && !strcmp(ubs->drv->format_name, "raw") && ubs->file &&
+ubs->file->drv && ubs->file->drv->is_filter &&
+ubs->file->drv->has_single_child))
+{
+ubs = ubs->file;
+}
+
+info->filename= g_strdup(ubs->filename);
+info->format  = g_strdup(bdrv_get_format_name(ubs));
+
 info->virtual_size= total_sectors * 512;
 info->actual_size = bdrv_get_allocated_file_size(bs);
 info->has_actual_size = info->actual_size >= 0;
-- 
1.9.1




[Qemu-devel] [PATCH for-2.0] qom: Fix crash with qom-list and link properties

2014-04-10 Thread Cole Robinson
Commit 9561fda8d90e176bef598ba87c42a1bd6ad03ef7 changed the type of
'opaque' for link properties, but missed updating this call site.
Reproducer:

./x86_64-softmmu/qemu-system-x86_64 -qmp unix:./qmp.sock,server &
./scripts/qmp/qmp-shell ./qmp.sock
(QEMU) qom-list path=//machine/i440fx/pci.0/child[2]

Reported-by: Marcin Gibuła 
Signed-off-by: Cole Robinson 
---
 qom/object.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/qom/object.c b/qom/object.c
index f4de619..9a730e7 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1225,7 +1225,8 @@ Object *object_resolve_path_component(Object *parent, 
const gchar *part)
 }
 
 if (object_property_is_link(prop)) {
-return *(Object **)prop->opaque;
+LinkProperty *lprop = prop->opaque;
+return *lprop->child;
 } else if (object_property_is_child(prop)) {
 return prop->opaque;
 } else {
-- 
1.9.0




[Qemu-devel] [PATCH v3 07/12] block/json: Add bdrv_co_get_block_status()

2014-04-10 Thread Max Reitz
Implement this function by passing it through to bs->file.

Signed-off-by: Max Reitz 
---
 block/json.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/block/json.c b/block/json.c
index cb83780..dfeec81 100644
--- a/block/json.c
+++ b/block/json.c
@@ -110,6 +110,13 @@ static coroutine_fn int 
json_co_write_zeroes(BlockDriverState *bs,
 return bdrv_co_write_zeroes(bs->file, sector_num, nb_sectors, flags);
 }
 
+static coroutine_fn int64_t json_co_get_block_status(BlockDriverState *bs,
+ int64_t sector_num,
+ int nb_sectors, int *pnum)
+{
+return bdrv_get_block_status(bs->file, sector_num, nb_sectors, pnum);
+}
+
 static void json_invalidate_cache(BlockDriverState *bs, Error **errp)
 {
 return bdrv_invalidate_cache(bs->file, errp);
@@ -156,6 +163,7 @@ static BlockDriver bdrv_json = {
 .bdrv_aio_discard   = json_aio_discard,
 
 .bdrv_co_write_zeroes   = json_co_write_zeroes,
+.bdrv_co_get_block_status   = json_co_get_block_status,
 
 .bdrv_invalidate_cache  = json_invalidate_cache,
 
-- 
1.9.1




[Qemu-devel] [PATCH v3 09/12] block/json: Add bdrv_get_specific_info()

2014-04-10 Thread Max Reitz
Add a passthrough function for bdrv_get_specific_info().

Signed-off-by: Max Reitz 
Reviewed-by: Benoit Canet 
---
 block/json.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/block/json.c b/block/json.c
index 0c7d90d..d9348bc 100644
--- a/block/json.c
+++ b/block/json.c
@@ -181,6 +181,11 @@ static int json_get_info(BlockDriverState *bs, 
BlockDriverInfo *bdi)
 return bdrv_get_info(bs->file, bdi);
 }
 
+static ImageInfoSpecific *json_get_specific_info(BlockDriverState *bs)
+{
+return bdrv_get_specific_info(bs->file);
+}
+
 static BlockDriver bdrv_json = {
 .format_name= "json",
 .protocol_name  = "json",
@@ -214,6 +219,7 @@ static BlockDriver bdrv_json = {
 .bdrv_has_zero_init = json_has_zero_init,
 .bdrv_refresh_limits= json_refresh_limits,
 .bdrv_get_info  = json_get_info,
+.bdrv_get_specific_info = json_get_specific_info,
 
 .is_filter  = true,
 .has_single_child   = true,
-- 
1.9.1




[Qemu-devel] [PATCH v3 06/12] block/json: Add functions for writing zeroes etc.

2014-04-10 Thread Max Reitz
Add passthrough functions for bdrv_aio_discard(),
bdrv_co_write_zeroes(), bdrv_truncate() and bdrv_has_zero_init().

Signed-off-by: Max Reitz 
Reviewed-by: Benoit Canet 
---
 block/json.c | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/block/json.c b/block/json.c
index 0e2d518..cb83780 100644
--- a/block/json.c
+++ b/block/json.c
@@ -95,6 +95,21 @@ static BlockDriverAIOCB *json_aio_flush(BlockDriverState *bs,
 return bdrv_aio_flush(bs->file, cb, opaque);
 }
 
+static BlockDriverAIOCB *json_aio_discard(BlockDriverState *bs,
+  int64_t sector_num, int nb_sectors,
+  BlockDriverCompletionFunc *cb,
+  void *opaque)
+{
+return bdrv_aio_discard(bs->file, sector_num, nb_sectors, cb, opaque);
+}
+
+static coroutine_fn int json_co_write_zeroes(BlockDriverState *bs,
+ int64_t sector_num, int 
nb_sectors,
+ BdrvRequestFlags flags)
+{
+return bdrv_co_write_zeroes(bs->file, sector_num, nb_sectors, flags);
+}
+
 static void json_invalidate_cache(BlockDriverState *bs, Error **errp)
 {
 return bdrv_invalidate_cache(bs->file, errp);
@@ -105,6 +120,16 @@ static int64_t json_getlength(BlockDriverState *bs)
 return bdrv_getlength(bs->file);
 }
 
+static int json_truncate(BlockDriverState *bs, int64_t offset)
+{
+return bdrv_truncate(bs->file, offset);
+}
+
+static int json_has_zero_init(BlockDriverState *bs)
+{
+return bdrv_has_zero_init(bs->file);
+}
+
 static int json_refresh_limits(BlockDriverState *bs)
 {
 bs->bl = bs->file->bl;
@@ -128,12 +153,17 @@ static BlockDriver bdrv_json = {
 .bdrv_aio_readv = json_aio_readv,
 .bdrv_aio_writev= json_aio_writev,
 .bdrv_aio_flush = json_aio_flush,
+.bdrv_aio_discard   = json_aio_discard,
+
+.bdrv_co_write_zeroes   = json_co_write_zeroes,
 
 .bdrv_invalidate_cache  = json_invalidate_cache,
 
 .has_variable_length= true,
 .bdrv_getlength = json_getlength,
+.bdrv_truncate  = json_truncate,
 
+.bdrv_has_zero_init = json_has_zero_init,
 .bdrv_refresh_limits= json_refresh_limits,
 .bdrv_get_info  = json_get_info,
 
-- 
1.9.1




[Qemu-devel] [PATCH v3 08/12] block/json: Add ioctl etc.

2014-04-10 Thread Max Reitz
Add passthrough functions for bdrv_aio_ioctl(), bdrv_is_inserted(),
bdrv_media_changed(), bdrv_eject(), bdrv_lock_medium() and bdrv_ioctl().

Signed-off-by: Max Reitz 
Reviewed-by: Benoit Canet 
---
 block/json.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/block/json.c b/block/json.c
index dfeec81..0c7d90d 100644
--- a/block/json.c
+++ b/block/json.c
@@ -103,6 +103,14 @@ static BlockDriverAIOCB *json_aio_discard(BlockDriverState 
*bs,
 return bdrv_aio_discard(bs->file, sector_num, nb_sectors, cb, opaque);
 }
 
+static BlockDriverAIOCB *json_aio_ioctl(BlockDriverState *bs,
+unsigned long int req, void *buf,
+BlockDriverCompletionFunc *cb,
+void *opaque)
+{
+return bdrv_aio_ioctl(bs->file, req, buf, cb, opaque);
+}
+
 static coroutine_fn int json_co_write_zeroes(BlockDriverState *bs,
  int64_t sector_num, int 
nb_sectors,
  BdrvRequestFlags flags)
@@ -117,6 +125,31 @@ static coroutine_fn int64_t 
json_co_get_block_status(BlockDriverState *bs,
 return bdrv_get_block_status(bs->file, sector_num, nb_sectors, pnum);
 }
 
+static int json_is_inserted(BlockDriverState *bs)
+{
+return bdrv_is_inserted(bs->file);
+}
+
+static int json_media_changed(BlockDriverState *bs)
+{
+return bdrv_media_changed(bs->file);
+}
+
+static void json_eject(BlockDriverState *bs, bool eject_flag)
+{
+bdrv_eject(bs->file, eject_flag);
+}
+
+static void json_lock_medium(BlockDriverState *bs, bool locked)
+{
+bdrv_lock_medium(bs->file, locked);
+}
+
+static int json_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
+{
+return bdrv_ioctl(bs->file, req, buf);
+}
+
 static void json_invalidate_cache(BlockDriverState *bs, Error **errp)
 {
 return bdrv_invalidate_cache(bs->file, errp);
@@ -161,10 +194,17 @@ static BlockDriver bdrv_json = {
 .bdrv_aio_writev= json_aio_writev,
 .bdrv_aio_flush = json_aio_flush,
 .bdrv_aio_discard   = json_aio_discard,
+.bdrv_aio_ioctl = json_aio_ioctl,
 
 .bdrv_co_write_zeroes   = json_co_write_zeroes,
 .bdrv_co_get_block_status   = json_co_get_block_status,
 
+.bdrv_is_inserted   = json_is_inserted,
+.bdrv_media_changed = json_media_changed,
+.bdrv_eject = json_eject,
+.bdrv_lock_medium   = json_lock_medium,
+.bdrv_ioctl = json_ioctl,
+
 .bdrv_invalidate_cache  = json_invalidate_cache,
 
 .has_variable_length= true,
-- 
1.9.1




[Qemu-devel] [PATCH v3 05/12] block/json: Add functions for cache control

2014-04-10 Thread Max Reitz
Add passthrough functions for bdrv_aio_flush() and
bdrv_invalidate_cache().

Signed-off-by: Max Reitz 
---
 block/json.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/block/json.c b/block/json.c
index 591bc47..0e2d518 100644
--- a/block/json.c
+++ b/block/json.c
@@ -88,6 +88,18 @@ static BlockDriverAIOCB *json_aio_writev(BlockDriverState 
*bs,
 return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
 }
 
+static BlockDriverAIOCB *json_aio_flush(BlockDriverState *bs,
+BlockDriverCompletionFunc *cb,
+void *opaque)
+{
+return bdrv_aio_flush(bs->file, cb, opaque);
+}
+
+static void json_invalidate_cache(BlockDriverState *bs, Error **errp)
+{
+return bdrv_invalidate_cache(bs->file, errp);
+}
+
 static int64_t json_getlength(BlockDriverState *bs)
 {
 return bdrv_getlength(bs->file);
@@ -115,6 +127,9 @@ static BlockDriver bdrv_json = {
 
 .bdrv_aio_readv = json_aio_readv,
 .bdrv_aio_writev= json_aio_writev,
+.bdrv_aio_flush = json_aio_flush,
+
+.bdrv_invalidate_cache  = json_invalidate_cache,
 
 .has_variable_length= true,
 .bdrv_getlength = json_getlength,
-- 
1.9.1




Re: [Qemu-devel] qemu 2.0.0-rc2 crash

2014-04-10 Thread Cole Robinson
On 04/10/2014 02:15 PM, Cole Robinson wrote:
> On 04/10/2014 12:39 PM, Marcel Apfelbaum wrote:
>> On Thu, 2014-04-10 at 18:24 +0200, Marcin Gibuła wrote:
>>> W dniu 2014-04-10 15:43, Marcel Apfelbaum pisze:
 On Thu, 2014-04-10 at 14:55 +0200, Marcin Gibuła wrote:
> Hi,
>
> I've been playing with QEMU 2.0-rc2 and found a crash that isn't there
> in 1.7.1.
 Hi Marcin,
 Thanks for reporting the bug!

 Do you have a development environment?
 If you do, and the reproduction is fast (and you already have a setup),
 a git bisect to find the problematic commit would be appreciated,
>>>
>>> Hi,
>>>
>>> yes, it's on development environment. If you could point me to some 
>>> quick guide to bisecting qemu, I'll be happy to do it.
>>
>> Sure! Thanks for helping.
>>
>> 1. Start:
>>  git bisect start
>>  git bisect good  
>> (Ex: v1.7.1)
>>  git bisect bad  
>> (Ex: HEAD)
>> 2. Git will checkout commits for you and you have to check and answer:
>>  git bisect good or git bisect bad 
>> 3. Git will show you the first bad commit.
>>
>> A more detailed version here:
>> http://git-scm.com/book/en/Git-Tools-Debugging-with-Git
>> Look for git-bisect.
> 
> Actually I was just independently bisecting this :) Culprit is:
> 
> commit 9561fda8d90e176bef598ba87c42a1bd6ad03ef7
> Author: Stefan Hajnoczi 
> Date:   Wed Mar 19 08:58:55 2014 +0100
> 
> qom: Make QOM link property unref optional
> 
> Simple reproducer:
> 
> ./x86_64-softmmu/qemu-system-x86_64 -qmp unix:./qmp.sock,server
> 
> ./scripts/qmp/qmp-shell ./qmp.sock
> (QEMU) qom-list path=//machine/i440fx/pci.0/child[2]
> 
> Seems like trying to qom-list any link property will crash
> 

I think this is the fix:

diff --git a/qom/object.c b/qom/object.c
index f4de619..9a730e7 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1225,7 +1225,8 @@ Object *object_resolve_path_component(Object *parent, cons
 }

 if (object_property_is_link(prop)) {
-return *(Object **)prop->opaque;
+LinkProperty *lprop = prop->opaque;
+return *lprop->child;
 } else if (object_property_is_child(prop)) {
 return prop->opaque;
 } else {

The commit mentioned above changed the type of opaque for link properties, but
forgot to update this site. I'll send a top level patch.

- Cole




Re: [Qemu-devel] qemu 2.0.0-rc2 crash

2014-04-10 Thread Cole Robinson
On 04/10/2014 02:15 PM, Cole Robinson wrote:
> On 04/10/2014 12:39 PM, Marcel Apfelbaum wrote:
>> On Thu, 2014-04-10 at 18:24 +0200, Marcin Gibuła wrote:
>>> W dniu 2014-04-10 15:43, Marcel Apfelbaum pisze:
 On Thu, 2014-04-10 at 14:55 +0200, Marcin Gibuła wrote:
> Hi,
>
> I've been playing with QEMU 2.0-rc2 and found a crash that isn't there
> in 1.7.1.
 Hi Marcin,
 Thanks for reporting the bug!

 Do you have a development environment?
 If you do, and the reproduction is fast (and you already have a setup),
 a git bisect to find the problematic commit would be appreciated,
>>>
>>> Hi,
>>>
>>> yes, it's on development environment. If you could point me to some 
>>> quick guide to bisecting qemu, I'll be happy to do it.
>>
>> Sure! Thanks for helping.
>>
>> 1. Start:
>>  git bisect start
>>  git bisect good  
>> (Ex: v1.7.1)
>>  git bisect bad  
>> (Ex: HEAD)
>> 2. Git will checkout commits for you and you have to check and answer:
>>  git bisect good or git bisect bad 
>> 3. Git will show you the first bad commit.
>>
>> A more detailed version here:
>> http://git-scm.com/book/en/Git-Tools-Debugging-with-Git
>> Look for git-bisect.
> 
> Actually I was just independently bisecting this :) Culprit is:
> 
> commit 9561fda8d90e176bef598ba87c42a1bd6ad03ef7
> Author: Stefan Hajnoczi 
> Date:   Wed Mar 19 08:58:55 2014 +0100
> 
> qom: Make QOM link property unref optional
> 
> Simple reproducer:
> 
> ./x86_64-softmmu/qemu-system-x86_64 -qmp unix:./qmp.sock,server
> 
> ./scripts/qmp/qmp-shell ./qmp.sock
> (QEMU) qom-list path=//machine/i440fx/pci.0/child[2]
> 
> Seems like trying to qom-list any link property will crash
> 

I think this is the fix;




Re: [Qemu-devel] [PATCH 1/1] kvm_physical_sync_dirty_bitmap: ignore ENOENT from kvm_vm_ioctl

2014-04-10 Thread Serge Hallyn
Quoting Michael Tokarev (m...@tls.msk.ru):
> 09.04.2014 07:21, Serge Hallyn wrote:
> > ENOENT (iiuc) means the kernel has an empty dirty bitmap for this
> > slot.  Don't abort in that case.  This appears to solve the bug
> > reported at
> > 
> > https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/1303926
> > 
> > which first showed up with commit b533f658a98325d: fix return check for
> > KVM_GET_DIRTY_LOG ioctl
> > 
> > Signed-off-by: Serge Hallyn 
> > ---
> >  kvm-all.c | 5 -
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/kvm-all.c b/kvm-all.c
> > index 82a9119..7b7ea8d 100644
> > --- a/kvm-all.c
> > +++ b/kvm-all.c
> > @@ -441,10 +441,13 @@ static int 
> > kvm_physical_sync_dirty_bitmap(MemoryRegionSection *section)
> >  
> >  d.slot = mem->slot;
> >  
> > -if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) {
> > +ret = kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d);
> > +if (ret < 0 && ret != -ENOENT) {
> >  DPRINTF("ioctl failed %d\n", errno);
> >  ret = -1;
> >  break;
> > +} else if (ret < 0) {
> > +ret = 0;
> >  }
> >  
> >  kvm_get_dirty_pages_log_range(section, d.dirty_bitmap);
> 
> Should we omit calling kvm_get_dirty_pages_log_range() if there's
> no bitmap from kernel?

If that's something we can know then certainly that'll be better.
It'll save an ioctl and copy_from_user of the whole of &d.

> In particular, do we trust kernel to not
> touch d.dirty_bitmap when it returns ENOENT?

Seems ok, kvm_vm_ioctl_get_dirty_log() doesn't change anything
in *log before returning when it finds no dirty_mapslot.

-serge



Re: [Qemu-devel] [PATCH V4 2/2] hw/pci: check if pci2pci bridges implement optional limit registers

2014-04-10 Thread Michael S. Tsirkin
On Thu, Apr 10, 2014 at 08:44:18PM +0300, Marcel Apfelbaum wrote:
>  pair and
>  pair
> are both optional.
> Do not reserve ranges if the above registers are not implemented.
> 
> Signed-off-by: Marcel Apfelbaum 
> ---
>  src/fw/pciinit.c |  9 ++---
>  src/hw/pci.c | 34 ++
>  src/hw/pci.h |  9 +
>  3 files changed, 45 insertions(+), 7 deletions(-)
> 
> diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
> index 9b5d7ad..bbaecd6 100644
> --- a/src/fw/pciinit.c
> +++ b/src/fw/pciinit.c
> @@ -26,13 +26,6 @@
>  #define PCI_BRIDGE_MEM_MIN(1<<21)  // 2M == hugepage size
>  #define PCI_BRIDGE_IO_MIN  0x1000  // mandated by pci bridge spec
>  
> -enum pci_region_type {
> -PCI_REGION_TYPE_IO,
> -PCI_REGION_TYPE_MEM,
> -PCI_REGION_TYPE_PREFMEM,
> -PCI_REGION_TYPE_COUNT,
> -};
> -
>  static const char *region_type_name[] = {
>  [ PCI_REGION_TYPE_IO ]  = "io",
>  [ PCI_REGION_TYPE_MEM ] = "mem",
> @@ -681,6 +674,8 @@ static int pci_bios_check_devices(struct pci_bus *busses)
>  for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
>  u64 align = (type == PCI_REGION_TYPE_IO) ?
>  PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
> +if (!pci_bridge_has_region(s->bus_dev, type))
> +continue;
>  if (pci_region_align(&s->r[type]) > align)
>   align = pci_region_align(&s->r[type]);
>  u64 sum = pci_region_sum(&s->r[type]);
> diff --git a/src/hw/pci.c b/src/hw/pci.c
> index 77cdba2..d5979af 100644
> --- a/src/hw/pci.c
> +++ b/src/hw/pci.c
> @@ -244,6 +244,40 @@ u8 pci_find_capability(struct pci_device *pci, u8 cap_id)
>  return 0;
>  }
>  
> +static int pci_config_is_reserved(struct pci_device *pci, u32 addr)

Why u32? It's u8 isn't it?

> +{
> +u8 val;
> +
> +val = pci_config_readb(pci->bdf, addr);
> +pci_config_writeb(pci->bdf, addr, 0xFF);
> +
> +if (!(pci_config_readb(pci->bdf, addr)))

() not needed after !

> +return 1;
> +
> +pci_config_writeb(pci->bdf, addr, val);
> +return 0;
> +}

Above read simply saves the register value, write now restores it.
It really should have a comment explaning what each stage does.

But I don't see why we still waste cycles on this save/restore
dance. This is simply the result of making the API too generic.
Open-code it below, and add a comment:


/* Test whether bridge support forwarding of transactions
 * of a specific type.
 * Note: disables bridge's window registers as a side effect.
 */
int pci_bridge_has_region(struct pci_device *pci,
  enum pci_region_type region_type)
{
u8 base;

switch (region_type) {
case PCI_REGION_TYPE_IO:
base = PCI_IO_BASE;
break;
case PCI_REGION_TYPE_PREFMEM:
base = PCI_PREF_MEMORY_BASE;
break;
default:
/* Regular memory support is mandatory */
return 1;
}

pci_config_writeb(pci->bdf, addr, 0xFF);

return pci_config_readb(pci->bdf, addr) != 0;
}

> +
>  void
>  pci_reboot(void)
>  {
> diff --git a/src/hw/pci.h b/src/hw/pci.h
> index e828225..0aaa84c 100644
> --- a/src/hw/pci.h
> +++ b/src/hw/pci.h
> @@ -12,6 +12,13 @@
>  #define PCI_NUM_REGIONS 7
>  #define PCI_BRIDGE_NUM_REGIONS 2
>  
> +enum pci_region_type {
> +PCI_REGION_TYPE_IO,
> +PCI_REGION_TYPE_MEM,
> +PCI_REGION_TYPE_PREFMEM,
> +PCI_REGION_TYPE_COUNT,
> +};
> +
>  static inline u8 pci_bdf_to_bus(u16 bdf) {
>  return bdf >> 8;
>  }
> @@ -117,6 +124,8 @@ int pci_init_device(const struct pci_device_id *ids
>  struct pci_device *pci_find_init_device(const struct pci_device_id *ids
>  , void *arg);
>  u8 pci_find_capability(struct pci_device *pci, u8 cap_id);
> +int pci_bridge_has_region(struct pci_device *pci,
> +  enum pci_region_type region_type);
>  void pci_reboot(void);
>  
>  #endif
> -- 
> 1.8.3.1
> 



[Qemu-devel] [PATCH V5 2/2] hw/pci: check if pci2pci bridges implement optional limit registers

2014-04-10 Thread Marcel Apfelbaum
 pair and
 pair
are both optional.
Do not reserve ranges if the above registers are not implemented.

Signed-off-by: Marcel Apfelbaum 
---
 src/fw/pciinit.c |  9 ++---
 src/hw/pci.c | 26 ++
 src/hw/pci.h |  9 +
 3 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
index 9b5d7ad..bbaecd6 100644
--- a/src/fw/pciinit.c
+++ b/src/fw/pciinit.c
@@ -26,13 +26,6 @@
 #define PCI_BRIDGE_MEM_MIN(1<<21)  // 2M == hugepage size
 #define PCI_BRIDGE_IO_MIN  0x1000  // mandated by pci bridge spec
 
-enum pci_region_type {
-PCI_REGION_TYPE_IO,
-PCI_REGION_TYPE_MEM,
-PCI_REGION_TYPE_PREFMEM,
-PCI_REGION_TYPE_COUNT,
-};
-
 static const char *region_type_name[] = {
 [ PCI_REGION_TYPE_IO ]  = "io",
 [ PCI_REGION_TYPE_MEM ] = "mem",
@@ -681,6 +674,8 @@ static int pci_bios_check_devices(struct pci_bus *busses)
 for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
 u64 align = (type == PCI_REGION_TYPE_IO) ?
 PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
+if (!pci_bridge_has_region(s->bus_dev, type))
+continue;
 if (pci_region_align(&s->r[type]) > align)
  align = pci_region_align(&s->r[type]);
 u64 sum = pci_region_sum(&s->r[type]);
diff --git a/src/hw/pci.c b/src/hw/pci.c
index 77cdba2..390b4dd 100644
--- a/src/hw/pci.c
+++ b/src/hw/pci.c
@@ -244,6 +244,32 @@ u8 pci_find_capability(struct pci_device *pci, u8 cap_id)
 return 0;
 }
 
+/* Test whether bridge support forwarding of transactions
+ * of a specific type.
+ * Note: disables bridge's window registers as a side effect.
+ */
+int pci_bridge_has_region(struct pci_device *pci,
+enum pci_region_type region_type)
+{
+u8 base;
+
+switch (region_type) {
+case PCI_REGION_TYPE_IO:
+base = PCI_IO_BASE;
+break;
+case PCI_REGION_TYPE_PREFMEM:
+base = PCI_PREF_MEMORY_BASE;
+break;
+default:
+/* Regular memory support is mandatory */
+return 1;
+}
+
+pci_config_writeb(pci->bdf, base, 0xFF);
+
+return pci_config_readb(pci->bdf, base) != 0;
+}
+
 void
 pci_reboot(void)
 {
diff --git a/src/hw/pci.h b/src/hw/pci.h
index e828225..0aaa84c 100644
--- a/src/hw/pci.h
+++ b/src/hw/pci.h
@@ -12,6 +12,13 @@
 #define PCI_NUM_REGIONS 7
 #define PCI_BRIDGE_NUM_REGIONS 2
 
+enum pci_region_type {
+PCI_REGION_TYPE_IO,
+PCI_REGION_TYPE_MEM,
+PCI_REGION_TYPE_PREFMEM,
+PCI_REGION_TYPE_COUNT,
+};
+
 static inline u8 pci_bdf_to_bus(u16 bdf) {
 return bdf >> 8;
 }
@@ -117,6 +124,8 @@ int pci_init_device(const struct pci_device_id *ids
 struct pci_device *pci_find_init_device(const struct pci_device_id *ids
 , void *arg);
 u8 pci_find_capability(struct pci_device *pci, u8 cap_id);
+int pci_bridge_has_region(struct pci_device *pci,
+  enum pci_region_type region_type);
 void pci_reboot(void);
 
 #endif
-- 
1.8.3.1




[Qemu-devel] [PATCH V5 1/2] hw/pci: reserve IO and mem for pci-2-pci bridges with no devices attached

2014-04-10 Thread Marcel Apfelbaum
If a pci-2-pci bridge supports hot-plug functionality but there are no devices
connected to it, reserve IO/mem in order to be able to attach devices
later. Do not waste space, use minimum allowed.

Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Marcel Apfelbaum 
---
 src/fw/pciinit.c |  3 +++
 src/hw/pci.c | 19 +++
 src/hw/pci.h |  1 +
 3 files changed, 23 insertions(+)

diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
index 64f1d41..9b5d7ad 100644
--- a/src/fw/pciinit.c
+++ b/src/fw/pciinit.c
@@ -677,12 +677,15 @@ static int pci_bios_check_devices(struct pci_bus *busses)
 continue;
 struct pci_bus *parent = &busses[pci_bdf_to_bus(s->bus_dev->bdf)];
 int type;
+u8 shpc_cap = pci_find_capability(s->bus_dev, PCI_CAP_ID_SHPC);
 for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
 u64 align = (type == PCI_REGION_TYPE_IO) ?
 PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
 if (pci_region_align(&s->r[type]) > align)
  align = pci_region_align(&s->r[type]);
 u64 sum = pci_region_sum(&s->r[type]);
+if (!sum && shpc_cap)
+sum = align; /* reserve min size for hot-plug */
 u64 size = ALIGN(sum, align);
 int is64 = pci_bios_bridge_region_is64(&s->r[type],
 s->bus_dev, type);
diff --git a/src/hw/pci.c b/src/hw/pci.c
index caf9265..77cdba2 100644
--- a/src/hw/pci.c
+++ b/src/hw/pci.c
@@ -225,6 +225,25 @@ pci_find_init_device(const struct pci_device_id *ids, void 
*arg)
 return NULL;
 }
 
+u8 pci_find_capability(struct pci_device *pci, u8 cap_id)
+{
+int i;
+u8 cap;
+u16 status = pci_config_readw(pci->bdf, PCI_STATUS);
+
+if (!(status & PCI_STATUS_CAP_LIST))
+return 0;
+
+cap = pci_config_readb(pci->bdf, PCI_CAPABILITY_LIST);
+for (i = 0; cap && i <= 0xff; i++) {
+if (pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_ID) == cap_id)
+return cap;
+cap = pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_NEXT);
+}
+
+return 0;
+}
+
 void
 pci_reboot(void)
 {
diff --git a/src/hw/pci.h b/src/hw/pci.h
index 167a027..e828225 100644
--- a/src/hw/pci.h
+++ b/src/hw/pci.h
@@ -116,6 +116,7 @@ int pci_init_device(const struct pci_device_id *ids
 , struct pci_device *pci, void *arg);
 struct pci_device *pci_find_init_device(const struct pci_device_id *ids
 , void *arg);
+u8 pci_find_capability(struct pci_device *pci, u8 cap_id);
 void pci_reboot(void);
 
 #endif
-- 
1.8.3.1




[Qemu-devel] [SeaBIOS [PATCH V5 0/2] hw/pci: reserve IO and mem for pci-2-pci bridges with no devices attached

2014-04-10 Thread Marcel Apfelbaum
v4 -> v5
 - Addressed Michael S. Tsirkin's comments (patch 2/2):
   - Open-coded pci_config_is_reserved() method.

v3 -> v4:
 - Addressed Kevin O'Connor's comments:
   - Refactored a for loop in patch 1/2.
 - Addressed Michael S. Tsirkin's comments (patch 2/2):
   - Removed not needed method
   - Test only base registers (dropped limits tests)
   - Renamed a helper method
   - Used 0xFF to test if the memory is reserved
   - Simplified code in pci_bridge_has_region
 - I did keep the code that restores base's address as I don't want
   to modify the registers in a 'query' method. (as replied on the mail thread)

v2 -> v3:
 - Addressed Michael S. Tsirkin's comments:
   - I/O and Prefetchable Memory are optional. Do not allocate ranges
 if they are not implemented (2/2).
 - Note that 2/2 patch can be seen as a separate fix. However, it
   is related to ranges reservation.

v1 -> v2:
 - Thanks Gerd Hoffmann for the review.
 - Addressed Michael S. Tsirkin's comments:
   - Limit capabilities query to 256 iterations, to make sure we
 don't get into an infinite loop with a broken device.


If a pci-2-pci bridge supports hot-plug functionality but there are no devices
connected to it, reserve IO/mem in order to be able to attach devices
later. Do not waste space, use minimum allowed.

Marcel Apfelbaum (2):
  hw/pci: reserve IO and mem for pci-2-pci bridges with no devices
attached
  hw/pci: check if pci2pci bridges implement optional limit registers

 src/fw/pciinit.c | 12 +---
 src/hw/pci.c | 45 +
 src/hw/pci.h | 10 ++
 3 files changed, 60 insertions(+), 7 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH v3 4/5] qemu-img: Specify backing file for commit

2014-04-10 Thread Max Reitz
Introduce a new parameter for qemu-img commit which may be used to
explicitly specify the backing file into which an image should be
committed if the backing chain has more than a single layer.

Signed-off-by: Max Reitz 
Reviewed-by: Eric Blake 
Reviewed-by: Fam Zheng 
---
 qemu-img-cmds.hx |  4 ++--
 qemu-img.c   | 22 +++---
 qemu-img.texi|  8 +++-
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 8bc55cd..e8a5d34 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -22,9 +22,9 @@ STEXI
 ETEXI
 
 DEF("commit", img_commit,
-"commit [-q] [-f fmt] [-t cache] [-p] filename")
+"commit [-q] [-f fmt] [-t cache] [-b base] [-p] filename")
 STEXI
-@item commit [-q] [-f @var{fmt}] [-t @var{cache}] [-p] @var{filename}
+@item commit [-q] [-f @var{fmt}] [-t @var{cache}] [-b @var{base}] [-p] 
@var{filename}
 ETEXI
 
 DEF("compare", img_compare,
diff --git a/qemu-img.c b/qemu-img.c
index 0c22b20..5052b6f 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -751,15 +751,16 @@ static void run_block_job(BlockJob *job, struct 
CommonBlockJobCBInfo *cbi)
 static int img_commit(int argc, char **argv)
 {
 int c, ret, flags;
-const char *filename, *fmt, *cache;
+const char *filename, *fmt, *cache, *base;
 BlockDriverState *bs, *base_bs;
 bool progress = false, quiet = false;
 Error *local_err = NULL;
 
 fmt = NULL;
 cache = BDRV_DEFAULT_CACHE;
+base = NULL;
 for(;;) {
-c = getopt(argc, argv, "f:ht:qp");
+c = getopt(argc, argv, "f:ht:b:qp");
 if (c == -1) {
 break;
 }
@@ -774,6 +775,9 @@ static int img_commit(int argc, char **argv)
 case 't':
 cache = optarg;
 break;
+case 'b':
+base = optarg;
+break;
 case 'p':
 progress = true;
 break;
@@ -808,12 +812,16 @@ static int img_commit(int argc, char **argv)
 qemu_progress_init(progress, 1.f);
 qemu_progress_print(0.f, 100);
 
-/* This is different from QMP, which by default uses the deepest file in 
the
- * backing chain (i.e., the very base); however, the traditional behavior 
of
- * qemu-img commit is using the immediate backing file. */
-base_bs = bs->backing_hd;
+if (base) {
+base_bs = bdrv_find_backing_image(bs, base);
+} else {
+/* This is different from QMP, which by default uses the deepest file 
in
+ * the backing chain (i.e., the very base); however, the traditional
+ * behavior of qemu-img commit is using the immediate backing file. */
+base_bs = bs->backing_hd;
+}
 if (!base_bs) {
-error_set(&local_err, QERR_BASE_NOT_FOUND, "NULL");
+error_set(&local_err, QERR_BASE_NOT_FOUND, base ?: "NULL");
 goto done;
 }
 
diff --git a/qemu-img.texi b/qemu-img.texi
index 1a9c08f..27b65ae 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -140,7 +140,7 @@ this case. @var{backing_file} will never be modified unless 
you use the
 The size can also be specified using the @var{size} option with @code{-o},
 it doesn't need to be specified separately in this case.
 
-@item commit [-q] [-f @var{fmt}] [-t @var{cache}] [-p] @var{filename}
+@item commit [-q] [-f @var{fmt}] [-t @var{cache}] [-b @var{base}] [-p] 
@var{filename}
 
 Commit the changes recorded in @var{filename} in its base image or backing 
file.
 If the backing file is smaller than the snapshot, then the backing file will be
@@ -149,6 +149,12 @@ the backing file, the backing file will not be truncated.  
If you want the
 backing file to match the size of the smaller snapshot, you can safely truncate
 it yourself once the commit operation successfully completes.
 
+If the backing chain of the given image file @var{filename} has more than one
+layer, the backing file into which the changes will be committed may be
+specified as @var{base} (which has to be part of @var{filename}'s backing
+chain). If @var{base} is not specified, the immediate backing file of the top
+image (which is @var{filename}) will be used.
+
 @item compare [-f @var{fmt}] [-F @var{fmt}] [-p] [-s] [-q] @var{filename1} 
@var{filename2}
 
 Check if two images have the same content. You can compare images with
-- 
1.9.1




  1   2   3   >