From nobody Thu May 15 23:31:25 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1504770784096766.403311438027; Thu, 7 Sep 2017 00:53:04 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 98E99356D0; Thu, 7 Sep 2017 07:53:02 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 70B4461F21; Thu, 7 Sep 2017 07:53:02 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id D49FC3FC74; Thu, 7 Sep 2017 07:53:01 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v877ijVX000796 for ; Thu, 7 Sep 2017 03:44:45 -0400 Received: by smtp.corp.redhat.com (Postfix) id 82DE7187BD; Thu, 7 Sep 2017 07:44:45 +0000 (UTC) Received: from mx1.redhat.com (ext-mx07.extmail.prod.ext.phx2.redhat.com [10.5.110.31]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7D7A060D10 for ; Thu, 7 Sep 2017 07:44:43 +0000 (UTC) Received: from relay.sw.ru (mailhub.sw.ru [195.214.232.25]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0D3E8C047B67 for ; Thu, 7 Sep 2017 07:44:41 +0000 (UTC) Received: from dim-vz7.qa.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v877icE4023693 for ; Thu, 7 Sep 2017 10:44:39 +0300 (MSK) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 98E99356D0 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 98E99356D0 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 0D3E8C047B67 Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=pass (p=none dis=none) header.from=virtuozzo.com Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=nshirokovskiy@virtuozzo.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 0D3E8C047B67 From: Nikolay Shirokovskiy To: libvir-list@redhat.com Date: Thu, 7 Sep 2017 10:44:16 +0300 Message-Id: <1504770256-674340-5-git-send-email-nshirokovskiy@virtuozzo.com> In-Reply-To: <1504770256-674340-1-git-send-email-nshirokovskiy@virtuozzo.com> References: <1504770256-674340-1-git-send-email-nshirokovskiy@virtuozzo.com> X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 07 Sep 2017 07:44:42 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 07 Sep 2017 07:44:42 +0000 (UTC) for IP:'195.214.232.25' DOMAIN:'mailhub.sw.ru' HELO:'relay.sw.ru' FROM:'nshirokovskiy@virtuozzo.com' RCPT:'' X-RedHat-Spam-Score: -0.001 (SPF_PASS) 195.214.232.25 mailhub.sw.ru 195.214.232.25 mailhub.sw.ru X-Scanned-By: MIMEDefang 2.78 on 10.5.110.31 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 4/4] iohelper: fix reading with O_DIRECT X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 07 Sep 2017 07:53:03 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" saferead is not suitable for direct reads. If file size is not multiple of align size then we get EINVAL on the read(2) that is supposed to return 0 because read buffer will not be aligned at this point. Let's not read again after partial read and check that we read everything by comparing the number of total bytes read against file size. --- src/util/iohelper.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/util/iohelper.c b/src/util/iohelper.c index fe15a92..32c5a89 100644 --- a/src/util/iohelper.c +++ b/src/util/iohelper.c @@ -78,10 +78,22 @@ runIO(const char *path, int fd, int oflags) fdoutname =3D "stdout"; /* To make the implementation simpler, we give up on any * attempt to use O_DIRECT in a non-trivial manner. */ - if (direct && ((end =3D lseek(fd, 0, SEEK_CUR)) !=3D 0)) { - virReportSystemError(end < 0 ? errno : EINVAL, "%s", - _("O_DIRECT read needs entire seekable fi= le")); - goto cleanup; + if (direct) { + if ((end =3D lseek(fd, 0, SEEK_CUR)) !=3D 0) { + virReportSystemError(end < 0 ? errno : EINVAL, "%s", + _("O_DIRECT read needs entire seekabl= e file")); + goto cleanup; + } + + if ((end =3D lseek(fd, 0, SEEK_END)) < 0) { + virReportSystemError(errno, "%s", _("can not seek file end= ")); + goto cleanup; + } + + if (lseek(fd, 0, SEEK_SET) < 0) { + virReportSystemError(errno, "%s", _("can not seek file beg= in")); + goto cleanup; + } } break; case O_WRONLY: @@ -109,7 +121,25 @@ runIO(const char *path, int fd, int oflags) while (1) { ssize_t got; =20 - if ((got =3D saferead(fdin, buf, buflen)) < 0) { + /* in case of O_DIRECT we cannot read again to check for EOF + * after partial buffer read as it is done in saferead */ + if (direct && fdin =3D=3D fd && end - total < buflen) { + if (total =3D=3D end) + break; + + while ((got =3D read(fd, buf, buflen)) < 0 && errno =3D=3D EIN= TR); + + if (got < end - total) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to read last chunk from %s"), + fdinname); + goto cleanup; + } + } else { + got =3D saferead(fdin, buf, buflen); + } + + if (got < 0) { virReportSystemError(errno, _("Unable to read %s"), fdinname); goto cleanup; } --=20 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list