[PATCH v3 7/7] block: check availablity for preadv/pwritev on mac

Joelle van Dyne posted 7 patches 5 years, 3 months ago
Maintainers: Laurent Vivier <laurent@vivier.eu>, Peter Maydell <peter.maydell@linaro.org>, Chris Wulff <crwulff@gmail.com>, Samuel Thibault <samuel.thibault@ens-lyon.org>, Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, Richard Henderson <rth@twiddle.net>, Michael Roth <mdroth@linux.vnet.ibm.com>, Max Reitz <mreitz@redhat.com>, Marek Vasut <marex@denx.de>, Thomas Huth <thuth@redhat.com>, Stefan Hajnoczi <stefanha@redhat.com>, Jason Wang <jasowang@redhat.com>, Kevin Wolf <kwolf@redhat.com>
There is a newer version of this series
[PATCH v3 7/7] block: check availablity for preadv/pwritev on mac
Posted by Joelle van Dyne 5 years, 3 months ago
macOS 11/iOS 14 added preadv/pwritev APIs. Due to weak linking, configure
will succeed with CONFIG_PREADV even when targeting a lower OS version. We
therefore need to check at run time if we can actually use these APIs.

Signed-off-by: Joelle van Dyne <j@getutm.app>
---
 block/file-posix.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/block/file-posix.c b/block/file-posix.c
index 5560fd20ac..b5a7ce483d 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1394,12 +1394,24 @@ static bool preadv_present = true;
 static ssize_t
 qemu_preadv(int fd, const struct iovec *iov, int nr_iov, off_t offset)
 {
+#ifdef CONFIG_DARWIN /* preadv introduced in macOS 11 */
+    if (!__builtin_available(macOS 11, iOS 14, watchOS 7, tvOS 14, *)) {
+        preadv_present = false;
+        return -ENOSYS;
+    } else
+#endif
     return preadv(fd, iov, nr_iov, offset);
 }
 
 static ssize_t
 qemu_pwritev(int fd, const struct iovec *iov, int nr_iov, off_t offset)
 {
+#ifdef CONFIG_DARWIN /* pwritev introduced in macOS 11 */
+    if (!__builtin_available(macOS 11, iOS 14, watchOS 7, tvOS 14, *)) {
+        preadv_present = false;
+        return -ENOSYS;
+    } else
+#endif
     return pwritev(fd, iov, nr_iov, offset);
 }
 
-- 
2.28.0


Re: [PATCH v3 7/7] block: check availablity for preadv/pwritev on mac
Posted by Stefan Hajnoczi 5 years, 3 months ago
On Tue, Oct 27, 2020 at 08:07:01PM -0700, Joelle van Dyne wrote:
> macOS 11/iOS 14 added preadv/pwritev APIs. Due to weak linking, configure
> will succeed with CONFIG_PREADV even when targeting a lower OS version. We
> therefore need to check at run time if we can actually use these APIs.
> 
> Signed-off-by: Joelle van Dyne <j@getutm.app>
> ---
>  block/file-posix.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)

What happens when preadv() is called prior to macOS 11/iOS 14?

If I understand correctly the runtime check is preferrable because
otherwise a binary compiled on recent macOS/iOS would ship with preadv()
support but fail when executed on an older macOS/iOS?
Re: [PATCH v3 7/7] block: check availablity for preadv/pwritev on mac
Posted by Joelle van Dyne 5 years, 3 months ago
If built with Xcode 11 (or below), a compile time error will occur due
to symbol not found. (QEMU's ./configure detects this and doesn't
enable it)
If built with Xcode 12 without the checks, a runtime error will occur.

-j

On Wed, Oct 28, 2020 at 5:23 AM Stefan Hajnoczi <stefanha@redhat.com> wrote:
>
> On Tue, Oct 27, 2020 at 08:07:01PM -0700, Joelle van Dyne wrote:
> > macOS 11/iOS 14 added preadv/pwritev APIs. Due to weak linking, configure
> > will succeed with CONFIG_PREADV even when targeting a lower OS version. We
> > therefore need to check at run time if we can actually use these APIs.
> >
> > Signed-off-by: Joelle van Dyne <j@getutm.app>
> > ---
> >  block/file-posix.c | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
>
> What happens when preadv() is called prior to macOS 11/iOS 14?
>
> If I understand correctly the runtime check is preferrable because
> otherwise a binary compiled on recent macOS/iOS would ship with preadv()
> support but fail when executed on an older macOS/iOS?

Re: [PATCH v3 7/7] block: check availablity for preadv/pwritev on mac
Posted by Stefan Hajnoczi 5 years, 3 months ago
On Wed, Oct 28, 2020 at 06:07:16PM -0700, Joelle van Dyne wrote:
> If built with Xcode 12 without the checks, a runtime error will occur.

If that runtime error is ENOSYS then it's handled by existing code:

  if (preadv_present) {
      nbytes = handle_aiocb_rw_vector(aiocb);
      if (nbytes == aiocb->aio_nbytes ||
          (nbytes < 0 && nbytes != -ENOSYS)) {
          goto out;
      }
      preadv_present = false;
  }

Why is additional code needed for iOS?

Stefan
Re: [PATCH v3 7/7] block: check availablity for preadv/pwritev on mac
Posted by Joelle van Dyne 5 years, 3 months ago
No it doesn't return ENOSYS. Dyld calls abort() when a weak link is
not resolved at the time of call.

-j

On Thu, Oct 29, 2020 at 12:54 AM Stefan Hajnoczi <stefanha@gmail.com> wrote:
>
> On Wed, Oct 28, 2020 at 06:07:16PM -0700, Joelle van Dyne wrote:
> > If built with Xcode 12 without the checks, a runtime error will occur.
>
> If that runtime error is ENOSYS then it's handled by existing code:
>
>   if (preadv_present) {
>       nbytes = handle_aiocb_rw_vector(aiocb);
>       if (nbytes == aiocb->aio_nbytes ||
>           (nbytes < 0 && nbytes != -ENOSYS)) {
>           goto out;
>       }
>       preadv_present = false;
>   }
>
> Why is additional code needed for iOS?
>
> Stefan