diff mbox

linux-aio: Handle io_submit() failure gracefully

Message ID 1470741619-23231-1-git-send-email-kwolf@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kevin Wolf Aug. 9, 2016, 11:20 a.m. UTC
It is generally not expected that io_submit() fails other than with
-EAGAIN, but corner cases like SELinux refusing I/O when permissions are
revoked are still possible. In this case, we shouldn't abort, but just
return an I/O error for the request.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/linux-aio.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

Comments

Stefan Hajnoczi Aug. 10, 2016, 9:32 a.m. UTC | #1
On Tue, Aug 09, 2016 at 01:20:19PM +0200, Kevin Wolf wrote:
> It is generally not expected that io_submit() fails other than with
> -EAGAIN, but corner cases like SELinux refusing I/O when permissions are
> revoked are still possible. In this case, we shouldn't abort, but just
> return an I/O error for the request.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  block/linux-aio.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)

Thanks, applied to my block tree:
https://github.com/stefanha/qemu/commits/block

Stefan
Christian Borntraeger Aug. 12, 2016, 7:38 a.m. UTC | #2
On 08/09/2016 01:20 PM, Kevin Wolf wrote:
> It is generally not expected that io_submit() fails other than with
> -EAGAIN, but corner cases like SELinux refusing I/O when permissions are
> revoked are still possible. In this case, we shouldn't abort, but just
> return an I/O error for the request.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Yes, we have seen this as well when having a disk accessed by two different
guests and quickly starting/stopping. AFAIK Bjoern or Boris are looking into
some libvirt fixes to prevent that race from being triggered by libvirt,
but having QEMU to not crash is certainly useful on its own.

Christian
> ---
>  block/linux-aio.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/block/linux-aio.c b/block/linux-aio.c
> index de3548f..e906abe 100644
> --- a/block/linux-aio.c
> +++ b/block/linux-aio.c
> @@ -221,7 +221,13 @@ static void ioq_submit(LinuxAioState *s)
>              break;
>          }
>          if (ret < 0) {
> -            abort();
> +            /* Fail the first request, retry the rest */
> +            aiocb = QSIMPLEQ_FIRST(&s->io_q.pending);
> +            QSIMPLEQ_REMOVE_HEAD(&s->io_q.pending, next);
> +            s->io_q.in_queue--;
> +            aiocb->ret = ret;
> +            qemu_laio_process_completion(aiocb);
> +            continue;
>          }
> 
>          s->io_q.in_flight += ret;
>
diff mbox

Patch

diff --git a/block/linux-aio.c b/block/linux-aio.c
index de3548f..e906abe 100644
--- a/block/linux-aio.c
+++ b/block/linux-aio.c
@@ -221,7 +221,13 @@  static void ioq_submit(LinuxAioState *s)
             break;
         }
         if (ret < 0) {
-            abort();
+            /* Fail the first request, retry the rest */
+            aiocb = QSIMPLEQ_FIRST(&s->io_q.pending);
+            QSIMPLEQ_REMOVE_HEAD(&s->io_q.pending, next);
+            s->io_q.in_queue--;
+            aiocb->ret = ret;
+            qemu_laio_process_completion(aiocb);
+            continue;
         }
 
         s->io_q.in_flight += ret;