Manually disable copy_file_range() on RedHat kernels
Calls to the copy_file_range()
system call on recent RedHat kernels
now fail with EOPNOTSUP
instead of ENOSYS
, which breaks any use of
IO.copy_stream
(e.g. used by CarrierWave) if NFS is used.
Ruby attempts to detect whether the kernel supports this system call, but the detection mechanism only checks whether this system call is defined, not whether it is actually supported. We manually patch this to disable the
copy_file_range()
.
Relates to:
- https://bugs.ruby-lang.org/issues/16965
- https://gitlab.com/gitlab-org/gitlab/-/issues/218999
- https://bugzilla.redhat.com/show_bug.cgi?id=1783554
Status
- Ruby maintainers are aware of this problem: https://bugs.ruby-lang.org/issues/16965#note-3.
- This problem can be reproduced by using CarrierWave on an NFS mount (see https://gitlab.com/gitlab-org/gitlab/-/issues/218999#note_363311211).
- It is bug in NFS that RedHat is addressing: https://bugzilla.redhat.com/show_bug.cgi?id=1783554
- Normally, Ruby 2.6.6 falls back to a normal copy if
copy_file_range
isENOSYS
is returned. However, the NFS client is returningEOPNOTSUP
, which causes a Ruby exception. - I've verified that this patch works around the problem.
If we don't want to ship this, we can wait for RedHat to release kernel-3.10.0-1148.el7
, but meanwhile customers may not be able to use GitLab.
I think I'm inclined to ship this now, especially since RedHat kernels no longer support copy_file_range()
, so we save ourselves a system call by disabling it outright.
Testing
Test builds in https://dev.gitlab.org/gitlab/omnibus-gitlab/-/merge_requests/191.
To reproduce the problem:
- Use a recent RHEL 7.7 system.
3.10.0-1127.8.2.el7.x86_64
has this issue. - Install GitLab.
- Configure an NFS mount.
- Point the uploads to the NFS mount
gitlab_rails['uploads_directory'] = "/mnt/share/uploads"
- Attempt to upload a profile picture.