[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v10 2/3] qemu-img info lists bitmap directory en
From: |
Andrey Shinkevich |
Subject: |
Re: [Qemu-devel] [PATCH v10 2/3] qemu-img info lists bitmap directory entries |
Date: |
Wed, 30 Jan 2019 19:26:58 +0000 |
On 30/01/2019 21:24, Eric Blake wrote:
> On 1/30/19 11:51 AM, Andrey Shinkevich wrote:
>> In the 'Format specific information' section of the 'qemu-img info'
>> command output, the supplemental information about existing QCOW2
>> bitmaps will be shown, such as a bitmap name, flags and granularity:
>>
>
>> +static Qcow2BitmapInfoFlagsList *get_bitmap_info_flags(uint32_t flags)
>> +{
>> + Qcow2BitmapInfoFlagsList *list = NULL;
>> + Qcow2BitmapInfoFlagsList **plist = &list;
>> + int i;
>> +
>> + static const struct {
>> + int bme; /* Bitmap directory entry flags */
>> + int info; /* The flags to report to the user */
>> + } map[] = {
>> + { BME_FLAG_IN_USE, QCOW2_BITMAP_INFO_FLAGS_IN_USE },
>> + { BME_FLAG_AUTO, QCOW2_BITMAP_INFO_FLAGS_AUTO },
>> + };
>> +
>> + int map_size = sizeof(map) / sizeof(map[0]);
>> +
>> + for (i = 0; i < map_size; ++i) {
>> + if (flags & map[i].bme) {
>> + Qcow2BitmapInfoFlagsList *entry =
>> + g_new0(Qcow2BitmapInfoFlagsList, 1);
>> + entry->value = map[i].info;
>> + *plist = entry;
>> + plist = &entry->next;
>
> Here's an idea for having runtime verification that our mapping of BME_
> flags to QAPI flags is complete. At the spots marked [1], add:
>
> flags &= ~map[i].bme;
>
>> + }
>> + }
>> +
>> + *plist = NULL;
>
> Dead assignment. plist is originally pointing to list (which was
> NULL-initialized at declaration), and is only ever changed to point to
> the list's next entry->next (which were NULL-initialized thanks to g_new0).
Yes, it is redundant due to the trailing '0' at g_new.
Agreed absolutely ))
>
> [1]
> assert(!flags);
>
>> +
>> + return list;
>> +}
>> +
>> +/*
>> + * qcow2_get_bitmap_info_list()
>> + * Returns a list of QCOW2 bitmap details.
>> + * In case of no bitmaps, the function returns NULL and
>> + * the @errp parameter is not set (for a 0-length list in the QMP).
>> + * When bitmap information can not be obtained, the function returns
>> + * NULL and the @errp parameter is set (for omitting the list in QMP).
>
> Comment is a bit stale, now that we aren't going to omit the list in
> QMP, but instead fail the QMP command outright.
Ouch! Missed out to correct that comment ((
>
>> + */
>> +Qcow2BitmapInfoList *qcow2_get_bitmap_info_list(BlockDriverState *bs,
>> + Error **errp)
>> +{
>> + BDRVQcow2State *s = bs->opaque;
>> + Qcow2BitmapList *bm_list;
>> + Qcow2Bitmap *bm;
>> + Qcow2BitmapInfoList *list = NULL;
>> + Qcow2BitmapInfoList **plist = &list;
>> +
>> + if (s->nb_bitmaps == 0) {
>> + return NULL;
>> + }
>> +
>> + bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
>> + s->bitmap_directory_size, errp);
>> + if (bm_list == NULL) {
>> + return NULL;
>> + }
>> +
>> + QSIMPLEQ_FOREACH(bm, bm_list, entry) {
>> + Qcow2BitmapInfo *info = g_new0(Qcow2BitmapInfo, 1);
>> + Qcow2BitmapInfoList *obj = g_new0(Qcow2BitmapInfoList, 1);
>> + info->granularity = 1U << bm->granularity_bits;
>> + info->name = g_strdup(bm->name);
>> + info->flags = get_bitmap_info_flags(bm->flags);
>
> [1]
> get_bitmap_info_flags(bm->flags & ~BME_RESERVED_FLAGS)
Thank you, we will discuss it...
>
>> + info->unknown_flags = bm->flags & BME_RESERVED_FLAGS;
>> + info->has_unknown_flags = !!info->unknown_flags;
>> + obj->value = info;
>> + *plist = obj;
>> + plist = &obj->next;
>> + }
>> +
>> + bitmap_list_free(bm_list);
>> +
>> + return list;
>> +}
>> +
>> int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool
>> *header_updated,
>> Error **errp)
>> {
>> diff --git a/block/qcow2.c b/block/qcow2.c
>> index 27e5a2c..4824ca8 100644
>> --- a/block/qcow2.c
>> +++ b/block/qcow2.c
>> @@ -4394,6 +4394,14 @@ static ImageInfoSpecific
>> *qcow2_get_specific_info(BlockDriverState *bs,
>> .refcount_bits = s->refcount_bits,
>> };
>> } else if (s->qcow_version == 3) {
>> + Qcow2BitmapInfoList *bitmaps;
>> + bitmaps = qcow2_get_bitmap_info_list(bs, &local_err);
>> + if (local_err) {
>> + error_propagate(errp, local_err);
>> + g_free(spec_info->u.qcow2.data);
>> + g_free(spec_info);
>
> I think it is cleaner to use qapi_free_ImageInfoSpecific(spec_info),
> which takes care of recursion without you having to analyze whether two
> g_free() calls are sufficient. Of course, for THAT to work, we need to
> fix the line above that does:
>
> .u.qcow2.data = g_new(ImageInfoSpecificQCow2, 1),
>
> to instead use g_new0(), since recursive freeing of uninitialized data
> is not a good idea (without your patch, g_new() was sufficient since all
> paths through the code either fully initialize or assert). So maybe
> your patch is the shortest that works, after all.
Yea, the invocation to qapi_free_ImageInfoSpecific(spec_info) looks like
a better code style.
>
>
>> +##
>> +# @Qcow2BitmapInfo:
>> +#
>> +# Qcow2 bitmap information.
>> +#
>> +# @name: the name of the bitmap
>> +#
>> +# @granularity: granularity of the bitmap in bytes
>> +#
>> +# @flags: recognized flags of the bitmap
>> +#
>> +# @unknown-flags: any remaining flags not recognized by the current qemu
>> version
>> +#
>> +# Since: 4.0
>> +##
>> +{ 'struct': 'Qcow2BitmapInfo',
>> + 'data': {'name': 'str', 'granularity': 'uint32',
>> + 'flags': ['Qcow2BitmapInfoFlags'],
>> + '*unknown-flags': 'uint32' } }
>
> Not for this patch, but how hard would it be to add a field showing the
> number of set bits in the bitmap?
I believe that is not too hard and would be happy to implement that with
another series, please.
>
> Kevin's insistence that a failure to read bitmap headers should fail the
> overall 'qemu-img info' (on the grounds that we're going to have
> problems using the image anyways) is reasonable enough; thanks for
> putting up with competing demands (such as my earlier ideas of how best
> to ignore read failures while still reporting as much remaining useful
> information as possible), even if it has taken us through v10 to get to
> a consensus on the semantics we want to support.
>
Both approaches looks reasonable to me.
"For by wise counsel thou shalt make thy war:
and in multitude of counselors there is safety."
--
With the best regards,
Andrey Shinkevich