Am 02.04.2013 um 13:47 hat Wenchao Xia geschrieben:
>   Now image info will be retrieved as an embbed json object inside
> BlockDeviceInfo, backing chain info and all related internal snapshot
> info can be got in the enhanced recursive structure of ImageInfo.
> 
> Signed-off-by: Wenchao Xia <xiaw...@linux.vnet.ibm.com>
> ---
>  block/qapi.c         |   38 ++++++++++++++++++++++++++--
>  include/block/qapi.h |    4 ++-
>  qapi-schema.json     |    5 +++-
>  qmp-commands.hx      |   67 
> +++++++++++++++++++++++++++++++++++++++++++++++++-
>  4 files changed, 108 insertions(+), 6 deletions(-)
> 
> diff --git a/block/qapi.c b/block/qapi.c
> index fa61c85..e98a028 100644
> --- a/block/qapi.c
> +++ b/block/qapi.c
> @@ -202,9 +202,14 @@ int bdrv_query_image_info(BlockDriverState *bs,
>      return 0;
>  }
>  
> -BlockInfo *bdrv_query_info(BlockDriverState *bs)
> +/* @p_info will be set only on success. */
> +void bdrv_query_info(BlockDriverState *bs,
> +                     BlockInfo **p_info,
> +                     Error **errp)
>  {
>      BlockInfo *info = g_malloc0(sizeof(*info));
> +    BlockDriverState *bs0;
> +    ImageInfo **p_image_info;
>      info->device = g_strdup(bs->device_name);
>      info->type = g_strdup("unknown");
>      info->locked = bdrv_dev_is_medium_locked(bs);
> @@ -258,8 +263,28 @@ BlockInfo *bdrv_query_info(BlockDriverState *bs)
>              info->inserted->iops_wr =
>                             bs->io_limits.iops[BLOCK_IO_LIMIT_WRITE];
>          }
> +
> +        bs0 = bs;
> +        p_image_info = &info->inserted->image;
> +        while (1) {
> +            if (bdrv_query_image_info(bs0, p_image_info, errp)) {
> +                goto err;
> +            }
> +            if (bs0->drv && bs0->backing_hd) {
> +                bs0 = bs0->backing_hd;
> +                (*p_image_info)->has_backing_image = true;
> +                p_image_info = &((*p_image_info)->backing_image);
> +            } else {
> +                break;
> +            }
> +        }
>      }
> -    return info;
> +
> +    *p_info = info;
> +    return;
> +
> + err:
> +    qapi_free_BlockInfo(info);
>  }
>  
>  SnapshotInfoList *qmp_query_snapshots(Error **errp)
> @@ -286,11 +311,18 @@ BlockInfoList *qmp_query_block(Error **errp)
>  
>      while ((bs = bdrv_next(bs))) {
>          BlockInfoList *info = g_malloc0(sizeof(*info));
> -        info->value = bdrv_query_info(bs);
> +        bdrv_query_info(bs, &info->value, errp);
> +        if (error_is_set(errp)) {
> +            goto err;
> +        }

This doesn't do what you think it does: The caller can pass NULL as
errp, and then this becomes never true. I think you need to use a
local_err and propagate it to errp in error cases.

>  
>          *p_next = info;
>          p_next = &info->next;
>      }
>  
>      return head;
> +
> + err:
> +    qapi_free_BlockInfoList(head);
> +    return NULL;
>  }

Kevin

Reply via email to