All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michal Privoznik <mprivozn@redhat.com>
To: Chun Yan Liu <cyliu@suse.com>, qemu-devel@nongnu.org
Cc: stefanha@redhat.com
Subject: Re: [Qemu-devel] [PATCH] qemu_opts_append: Play nicely with QemuOptsList's head
Date: Thu, 26 Jun 2014 08:33:52 +0200	[thread overview]
Message-ID: <53ABBED0.30309@redhat.com> (raw)
In-Reply-To: <53AC1875020000660003F55E@soto.provo.novell.com>

On 26.06.2014 06:56, Chun Yan Liu wrote:
>
>
>>>> On 6/25/2014 at 04:38 PM, in message
> <9ca16cc7ed58cd133ea2c8d86c29707b54005e1d.1403685480.git.mprivozn@redhat.com>,
> Michal Privoznik <mprivozn@redhat.com> wrote:
>> When running a libvirt test suite I've noticed the qemu-img is
>> crashing occasionally. Tracing the problem down led me to the
>> following valgrind output:
>>
>> qemu.git $ valgrind -q ./qemu-img create -f qed
>> -obacking_file=/dev/null,backing_fmt=raw qed
>> ==14881== Invalid write of size 8
>> ==14881==    at 0x1D263F: qemu_opts_create (qemu-option.c:692)
>> ==14881==    by 0x130782: bdrv_img_create (block.c:5531)
>> ==14881==    by 0x118DE0: img_create (qemu-img.c:462)
>> ==14881==    by 0x11E7E4: main (qemu-img.c:2830)
>> ==14881==  Address 0x11fedd38 is 24 bytes inside a block of size 232 free'd
>> ==14881==    at 0x4C2CA5E: realloc (in
>> /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
>> ==14881==    by 0x592D35E: g_realloc (in /usr/lib64/libglib-2.0.so.0.3800.2)
>> ==14881==    by 0x1D38D8: qemu_opts_append (qemu-option.c:1129)
>> ==14881==    by 0x13075E: bdrv_img_create (block.c:5528)
>> ==14881==    by 0x118DE0: img_create (qemu-img.c:462)
>> ==14881==    by 0x11E7E4: main (qemu-img.c:2830)
>> ==14881==
>> Formatting 'qed', fmt=qed size=0 backing_file='/dev/null' backing_fmt='raw'
>> cluster_size=65536
>> ==14881== Invalid write of size 8
>> ==14881==    at 0x1D28BE: qemu_opts_del (qemu-option.c:750)
>> ==14881==    by 0x130BF3: bdrv_img_create (block.c:5638)
>> ==14881==    by 0x118DE0: img_create (qemu-img.c:462)
>> ==14881==    by 0x11E7E4: main (qemu-img.c:2830)
>> ==14881==  Address 0x11fedd38 is 24 bytes inside a block of size 232 free'd
>> ==14881==    at 0x4C2CA5E: realloc (in
>> /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
>> ==14881==    by 0x592D35E: g_realloc (in /usr/lib64/libglib-2.0.so.0.3800.2)
>> ==14881==    by 0x1D38D8: qemu_opts_append (qemu-option.c:1129)
>> ==14881==    by 0x13075E: bdrv_img_create (block.c:5528)
>> ==14881==    by 0x118DE0: img_create (qemu-img.c:462)
>> ==14881==    by 0x11E7E4: main (qemu-img.c:2830)
>> ==14881==
>>
>> The problem is apparently in the qemu_opts_append(). Well, if it
>> gets called twice or more. On the first call, when @dst is NULL
>> some initialization is done during which @dst->head list gets
>> initialized. The list is initialized in a way, so that the list
>> tail points at the list head. However, the next time
>> qemu_opts_append() is called for new options to be added,
>> g_realloc() may move @dst at new address making the old list tail
>> point at invalid address. If that's the case we must update the
>> list pointers.
>>
>> Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
>> ---
>>   util/qemu-option.c | 11 ++++++++++-
>>   1 file changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/util/qemu-option.c b/util/qemu-option.c
>> index 43de3ad..6ad2cf2 100644
>> --- a/util/qemu-option.c
>> +++ b/util/qemu-option.c
>> @@ -1111,6 +1111,7 @@ QemuOptsList *qemu_opts_append(QemuOptsList *dst,
>>       size_t num_opts, num_dst_opts;
>>       QemuOptDesc *desc;
>>       bool need_init = false;
>> +    bool need_head_update;
>>
>>       if (!list) {
>>           return dst;
>> @@ -1121,6 +1122,12 @@ QemuOptsList *qemu_opts_append(QemuOptsList *dst,
>>        */
>>       if (!dst) {
>>           need_init = true;
>> +        need_head_update = true;
>
> Thanks very much for correction. But I think putting need_head_update here
> is a little odd. How about delete this line and ... [1]
>
>> +    } else {
>> +        /* Moreover, even if dst is not NULL, the realloc may move it at a
>> +         * different address in which case we may get a stale tail pointer
>> +         * in dst->head. */
>
> Only when dst->head is empty, we need to reinit, if dst->head->tqh_last points
> to other places already,  we should not reinit. How about make it more clear?
> e.g.
> If dst->head is empty, then (dst->head)->tqh_last = &(dst->head)->tqh_first; after
> g_realloc, (dst->head)->tqh_last may point to stail pointer, in this case, need to
> reinit dst->head.

Sure. But I wanted to avoid naming tqh_last or tqh_first explicitly as 
we have macros for that. Then, if we ever change the naming in 
include/qemu/queue.h we need to change this comment too.

>
>> +        need_head_update = QTAILQ_EMPTY(&dst->head);
>>       }
>>
>>       num_opts = count_opts_list(dst);
>> @@ -1131,9 +1138,11 @@ QemuOptsList *qemu_opts_append(QemuOptsList *dst,
>>       if (need_init) {
>>           dst->name = NULL;
>>           dst->implied_opt_name = NULL;
>> -        QTAILQ_INIT(&dst->head);
>
> [1] ... this line? (And initialize need_head_update = false.)

Yes, fix can be written in many ways. Then it's just the question of 
code style preference.

Michal

      reply	other threads:[~2014-06-26  6:34 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-25  8:38 [Qemu-devel] [PATCH] qemu_opts_append: Play nicely with QemuOptsList's head Michal Privoznik
2014-06-25 13:46 ` [Qemu-devel] [PATCH for 2.1] " Eric Blake
2014-06-26 13:56   ` Kevin Wolf
2014-06-26  4:56 ` [Qemu-devel] [PATCH] " Chun Yan Liu
2014-06-26  6:33   ` Michal Privoznik [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53ABBED0.30309@redhat.com \
    --to=mprivozn@redhat.com \
    --cc=cyliu@suse.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.