From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54079) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aldbz-0004Lg-KK for qemu-devel@nongnu.org; Thu, 31 Mar 2016 10:30:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aldbp-0008LS-Vd for qemu-devel@nongnu.org; Thu, 31 Mar 2016 10:30:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53956) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aldbp-0008LG-Qs for qemu-devel@nongnu.org; Thu, 31 Mar 2016 10:30:05 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 81C57C0B66F1 for ; Thu, 31 Mar 2016 14:30:05 +0000 (UTC) From: "Daniel P. Berrange" Date: Thu, 31 Mar 2016 15:29:56 +0100 Message-Id: <1459434597-31255-2-git-send-email-berrange@redhat.com> In-Reply-To: <1459434597-31255-1-git-send-email-berrange@redhat.com> References: <1459434597-31255-1-git-send-email-berrange@redhat.com> Subject: [Qemu-devel] [PATCH 1/2] char: fix broken EAGAIN retry on OS-X due to errno clobbering List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Paolo Bonzini Some of the chardev I/O paths really want to write the complete data buffer even though the channel is in non-blocking mode. To achieve this they look for EAGAIN and g_usleep() for 100ms. Unfortunately the code is set to check errno == EAGAIN a second time, after the g_usleep() call has completed. On OS-X at least, g_usleep clobbers errno to ETIMEDOUT, causing the retry to be skipped. This failure to retry means the full data isn't written to the chardev backend, which causes various failures including making the tests/ahci-test qtest hang. Rather than playing games trying to reset errno just simplify the code to use a goto to retry instead of a a loop. Signed-off-by: Daniel P. Berrange --- qemu-char.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 270819a..6e623c3 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -246,12 +246,12 @@ static int qemu_chr_fe_write_buffer(CharDriverState *s, const uint8_t *buf, int qemu_mutex_lock(&s->chr_write_lock); while (*offset < len) { - do { - res = s->chr_write(s, buf + *offset, len - *offset); - if (res == -1 && errno == EAGAIN) { - g_usleep(100); - } - } while (res == -1 && errno == EAGAIN); + retry: + res = s->chr_write(s, buf + *offset, len - *offset); + if (res < 0 && errno == EAGAIN) { + g_usleep(100); + goto retry; + } if (res <= 0) { break; @@ -333,12 +333,12 @@ int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len) } while (offset < len) { - do { - res = s->chr_sync_read(s, buf + offset, len - offset); - if (res == -1 && errno == EAGAIN) { - g_usleep(100); - } - } while (res == -1 && errno == EAGAIN); + retry: + res = s->chr_sync_read(s, buf + offset, len - offset); + if (res == -1 && errno == EAGAIN) { + g_usleep(100); + goto retry; + } if (res == 0) { break; -- 2.5.5