diff mbox

block/raw-posix: Open file descriptor O_RDWR to work around glibc posix_fallocate emulation issue.

Message ID 1443542050-26720-1-git-send-email-rjones@redhat.com
State New
Headers show

Commit Message

Richard W.M. Jones Sept. 29, 2015, 3:54 p.m. UTC
https://bugzilla.redhat.com/show_bug.cgi?id=1265196

The following command fails on an NFS mountpoint:

  $ qemu-img create -f qcow2 -o preallocation=falloc disk.img 262144
  Formatting 'disk.img', fmt=qcow2 size=262144 encryption=off cluster_size=65536 preallocation='falloc' lazy_refcounts=off
  qemu-img: disk.img: Could not preallocate data for the new file: Bad file descriptor

The reason turns out to be because NFS doesn't support the
posix_fallocate call.  glibc emulates it instead.  However glibc's
emulation involves using the pread(2) syscall.  The pread syscall
fails with EBADF if the file descriptor is opened without the read
open-flag (ie. open (..., O_WRONLY)).

I contacted glibc upstream about this, and their response is here:

  https://bugzilla.redhat.com/show_bug.cgi?id=1265196#c9

There are two possible fixes: Use Linux fallocate directly, or (this
fix) work around the problem in qemu by opening the file with O_RDWR
instead of O_WRONLY.

Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1265196
---
 block/raw-posix.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Kevin Wolf Sept. 30, 2015, 11:42 a.m. UTC | #1
Am 29.09.2015 um 17:54 hat Richard W.M. Jones geschrieben:
>   https://bugzilla.redhat.com/show_bug.cgi?id=1265196
> 
> The following command fails on an NFS mountpoint:
> 
>   $ qemu-img create -f qcow2 -o preallocation=falloc disk.img 262144
>   Formatting 'disk.img', fmt=qcow2 size=262144 encryption=off cluster_size=65536 preallocation='falloc' lazy_refcounts=off
>   qemu-img: disk.img: Could not preallocate data for the new file: Bad file descriptor
> 
> The reason turns out to be because NFS doesn't support the
> posix_fallocate call.  glibc emulates it instead.  However glibc's
> emulation involves using the pread(2) syscall.  The pread syscall
> fails with EBADF if the file descriptor is opened without the read
> open-flag (ie. open (..., O_WRONLY)).
> 
> I contacted glibc upstream about this, and their response is here:
> 
>   https://bugzilla.redhat.com/show_bug.cgi?id=1265196#c9
> 
> There are two possible fixes: Use Linux fallocate directly, or (this
> fix) work around the problem in qemu by opening the file with O_RDWR
> instead of O_WRONLY.
> 
> Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
> BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1265196

Thanks, applied to the block branch.

Kevin
Jeff Cody Sept. 30, 2015, 8:44 p.m. UTC | #2
On Tue, Sep 29, 2015 at 04:54:10PM +0100, Richard W.M. Jones wrote:
>   https://bugzilla.redhat.com/show_bug.cgi?id=1265196
> 
> The following command fails on an NFS mountpoint:
> 
>   $ qemu-img create -f qcow2 -o preallocation=falloc disk.img 262144
>   Formatting 'disk.img', fmt=qcow2 size=262144 encryption=off cluster_size=65536 preallocation='falloc' lazy_refcounts=off
>   qemu-img: disk.img: Could not preallocate data for the new file: Bad file descriptor
> 
> The reason turns out to be because NFS doesn't support the
> posix_fallocate call.  glibc emulates it instead.  However glibc's
> emulation involves using the pread(2) syscall.  The pread syscall
> fails with EBADF if the file descriptor is opened without the read
> open-flag (ie. open (..., O_WRONLY)).
> 
> I contacted glibc upstream about this, and their response is here:
> 
>   https://bugzilla.redhat.com/show_bug.cgi?id=1265196#c9
> 
> There are two possible fixes: Use Linux fallocate directly, or (this
> fix) work around the problem in qemu by opening the file with O_RDWR
> instead of O_WRONLY.
> 
> Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
> BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1265196
> ---
>  block/raw-posix.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/block/raw-posix.c b/block/raw-posix.c
> index 30df8ad..86f8562 100644
> --- a/block/raw-posix.c
> +++ b/block/raw-posix.c
> @@ -1648,7 +1648,7 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
>          goto out;
>      }
>  
> -    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
> +    fd = qemu_open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
>                     0644);
>      if (fd < 0) {
>          result = -errno;
> -- 
> 2.5.0
> 
>

Reviewed-by: Jeff Cody <jcody@redhat.com>
Eric Blake Oct. 1, 2015, 3:36 a.m. UTC | #3
On 09/29/2015 09:54 AM, Richard W.M. Jones wrote:
>   https://bugzilla.redhat.com/show_bug.cgi?id=1265196
> 
> The following command fails on an NFS mountpoint:
> 
>   $ qemu-img create -f qcow2 -o preallocation=falloc disk.img 262144
>   Formatting 'disk.img', fmt=qcow2 size=262144 encryption=off cluster_size=65536 preallocation='falloc' lazy_refcounts=off
>   qemu-img: disk.img: Could not preallocate data for the new file: Bad file descriptor
> 
> The reason turns out to be because NFS doesn't support the
> posix_fallocate call.  glibc emulates it instead.  However glibc's
> emulation involves using the pread(2) syscall.  The pread syscall
> fails with EBADF if the file descriptor is opened without the read
> open-flag (ie. open (..., O_WRONLY)).
> 

Failing with EBADF feels fishy (POSIX requests EINVAL in that case) -
but that's an upstream glibc discussion that has forked from this thread
and doesn't hold up the qemu fix.

> I contacted glibc upstream about this, and their response is here:
> 
>   https://bugzilla.redhat.com/show_bug.cgi?id=1265196#c9
> 
> There are two possible fixes: Use Linux fallocate directly, or (this
> fix) work around the problem in qemu by opening the file with O_RDWR
> instead of O_WRONLY.
> 
> Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
> BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1265196
> ---
>  block/raw-posix.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Eric Blake <eblake@redhat.com>
Peter Maydell Oct. 2, 2015, 2:36 p.m. UTC | #4
On 29 September 2015 at 16:54, Richard W.M. Jones <rjones@redhat.com> wrote:
>   https://bugzilla.redhat.com/show_bug.cgi?id=1265196
>
> The following command fails on an NFS mountpoint:
>
>   $ qemu-img create -f qcow2 -o preallocation=falloc disk.img 262144
>   Formatting 'disk.img', fmt=qcow2 size=262144 encryption=off cluster_size=65536 preallocation='falloc' lazy_refcounts=off
>   qemu-img: disk.img: Could not preallocate data for the new file: Bad file descriptor
>
> The reason turns out to be because NFS doesn't support the
> posix_fallocate call.  glibc emulates it instead.  However glibc's
> emulation involves using the pread(2) syscall.  The pread syscall
> fails with EBADF if the file descriptor is opened without the read
> open-flag (ie. open (..., O_WRONLY)).
>
> I contacted glibc upstream about this, and their response is here:
>
>   https://bugzilla.redhat.com/show_bug.cgi?id=1265196#c9

"You are not authorized to access bug #1265196."

Any chance of a working URL if we're going to immortalize it
in QEMU's git log?

thanks
-- PMM
Richard W.M. Jones Oct. 2, 2015, 2:43 p.m. UTC | #5
On Fri, Oct 02, 2015 at 03:36:04PM +0100, Peter Maydell wrote:
> On 29 September 2015 at 16:54, Richard W.M. Jones <rjones@redhat.com> wrote:
> >   https://bugzilla.redhat.com/show_bug.cgi?id=1265196
> >
> > The following command fails on an NFS mountpoint:
> >
> >   $ qemu-img create -f qcow2 -o preallocation=falloc disk.img 262144
> >   Formatting 'disk.img', fmt=qcow2 size=262144 encryption=off cluster_size=65536 preallocation='falloc' lazy_refcounts=off
> >   qemu-img: disk.img: Could not preallocate data for the new file: Bad file descriptor
> >
> > The reason turns out to be because NFS doesn't support the
> > posix_fallocate call.  glibc emulates it instead.  However glibc's
> > emulation involves using the pread(2) syscall.  The pread syscall
> > fails with EBADF if the file descriptor is opened without the read
> > open-flag (ie. open (..., O_WRONLY)).
> >
> > I contacted glibc upstream about this, and their response is here:
> >
> >   https://bugzilla.redhat.com/show_bug.cgi?id=1265196#c9
> 
> "You are not authorized to access bug #1265196."
> 
> Any chance of a working URL if we're going to immortalize it
> in QEMU's git log?

Sorry about that.  I have now made the bug public -- there was
absolutely no reason why it was private before.

Rich.
diff mbox

Patch

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 30df8ad..86f8562 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1648,7 +1648,7 @@  static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
         goto out;
     }
 
-    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
+    fd = qemu_open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
                    0644);
     if (fd < 0) {
         result = -errno;