[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb
From: |
Paolo Bonzini |
Subject: |
Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb |
Date: |
Wed, 21 Aug 2013 17:40:11 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130805 Thunderbird/17.0.8 |
Il 21/08/2013 17:24, Stefan Hajnoczi ha scritto:
> On Wed, Aug 21, 2013 at 10:02:47AM +0800, Asias He wrote:
>> In block/gluster.c, we have
>>
>> gluster_finish_aiocb
>> {
>> if (retval != sizeof(acb)) {
>> qemu_mutex_lock_iothread(); /* We are in gluster thread context */
>> ...
>> qemu_mutex_unlock_iothread();
>> }
>> }
>>
>> qemu tools, e.g. qemu-img, might race here because
>> qemu_mutex_{lock,unlock}_iothread are a nop operation and
>> gluster_finish_aiocb is in the gluster thread context.
>>
>> To fix, we introduce our own mutex for qemu tools.
>
> I think we need to look more closely at the error code path:
>
> acb->ret = ret;
> retval = qemu_write_full(s->fds[GLUSTER_FD_WRITE], &acb, sizeof(acb));
> if (retval != sizeof(acb)) {
> /*
> * Gluster AIO callback thread failed to notify the waiting
> * QEMU thread about IO completion.
> *
> * Complete this IO request and make the disk inaccessible for
> * subsequent reads and writes.
> */
> error_report("Gluster failed to notify QEMU about IO completion");
>
> qemu_mutex_lock_iothread(); /* We are in gluster thread context */
> acb->common.cb(acb->common.opaque, -EIO);
> qemu_aio_release(acb);
> close(s->fds[GLUSTER_FD_READ]);
> close(s->fds[GLUSTER_FD_WRITE]);
>
> Is it safe to close the fds? There is a race here:
>
> 1. Another thread opens a new file descriptor and gets GLUSTER_FD_READ or
> GLUSTER_FD_WRITE's old fd value.
> 2. Another gluster thread invokes the callback and does
> qemu_write_full(s->fds[GLUSTER_FD_WRITE], ...).
>
> Since the mutex doesn't protect s->fds[] this is possible.
>
> Maybe a simpler solution for request completion is:
>
> 1. Linked list of completed acbs.
> 2. Mutex to protect the linked list.
> 3. EventNotifier to signal iothread.
We could just use a bottom half, too. Add a bottom half to acb,
schedule it in gluster_finish_aiocb, delete it in the bottom half's own
callback.
Paolo
> Then this function becomes:
>
> static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
> {
> GlusterAIOCB *acb = arg;
> BlockDriverState *bs = acb->common.bs;
> BDRVGlusterState *s = bs->opaque;
> int retval;
>
> acb->ret = ret;
>
> qemu_mutex_lock(&s->finish_list_lock);
> QSIMPLEQ_INSERT_TAIL(&s->finish_list, acb, list);
> qemu_mutex_unlock(&s->finish_list_lock);
>
> event_notifier_set(&s->finish_list_notifier);
> }
>
> Stefan
>
>
- [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Asias He, 2013/08/20
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Paolo Bonzini, 2013/08/21
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Stefan Hajnoczi, 2013/08/21
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb,
Paolo Bonzini <=
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Bharata B Rao, 2013/08/22
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Stefan Hajnoczi, 2013/08/22
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Paolo Bonzini, 2013/08/22
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Bharata B Rao, 2013/08/22
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Paolo Bonzini, 2013/08/22
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Bharata B Rao, 2013/08/22
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Paolo Bonzini, 2013/08/22
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Bharata B Rao, 2013/08/22
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Paolo Bonzini, 2013/08/22
- Re: [Qemu-devel] [PATCH] block: Fix race in gluster_finish_aiocb, Bharata B Rao, 2013/08/22