-
Notifications
You must be signed in to change notification settings - Fork 951
rustup appears to depend on new-ish system call in linux #2472
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
copy_file_range is used by rust automatically on Linux - https://github.com/rust-lang/rust/blob/ac48e62db85e6db4bbe026490381ab205f4a614d/library/std/src/sys/unix/fs.rs#L1122 What you're seeing is just the automatic probing. Please provide the actual symptoms - run rustup with -v and provide the console output please. |
Hi Robert,
I'm aware of the probing often visible in strace, but the EOPNOTSUPP error immediately precedes the total abort of the update attempt. I can send the strace log if you want, but the console log is attached.
…On Sun, Aug 30, 2020 at 5:39pm Robert Collins ***@***.***> wrote:
copy_file_range is used by rust automatically on Linux -
https://github.com/rust-lang/rust/blob/ac48e62db85e6db4bbe026490381ab205f4a614d/library/std/src/sys/unix/fs.rs#L1122
What you're seeing is just the automatic probing. Please provide the
actual symptoms - run rustup with -v and provide the console output
please.
-- You are receiving this because you authored the thread. Reply to this
email directly or view it on GitHub:
#2472 (comment)
|
Since Rust is defined as needing 2.6.32/2.11 at minimum right now, it sounds like it should be working with 3.10/2.17. Could you please do as Robert asked and run |
Hi Daniel. Sorry, think I replied with console log earlier without posting. Here it is.
rustup.out: rustup.err: |
Okay I don't think anything else is triggering so perhaps another step is to try and create a minimal test case for using copy_file_range and replicate the failure on your system. Are you in a position to have a go at that? |
Sure and done. When I run the program inlined below I get the expected: Other possibly pertinent facts:
/**
* This program tests availability of copy_file_range on a system described
* by uname -a:
* Linux solu 3.10.0-1127.19.1.el7.x86_64 #1 SMP Tue Aug 25 17:23:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
*
* It was modeled on the following strace log:
*
* open("/research/users/rogerk/.rustup/tmp/e934jgtdi1tk6h56_file", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 4
* close(4) = 0
* lstat("/research/users/rogerk/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/components", {st_mode=S_IFREG|0700, st_size=212, ...}) = 0
* open("/research/users/rogerk/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/components", O_RDONLY|O_CLOEXEC) = 4
* fstat(4, {st_mode=S_IFREG|0700, st_size=212, ...}) = 0
* open("/research/users/rogerk/.rustup/tmp/e934jgtdi1tk6h56_file", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0100700) = 10
* fstat(10, {st_mode=S_IFREG|0700, st_size=0, ...}) = 0
* fchmod(10, 0100700) = 0
* copy_file_range(4, NULL, 10, NULL, 212, 0) = -1 EOPNOTSUPP (Operation not supported)
* close(10) = 0
* close(4) = 0
*
* Note that I have to define the syscall locally because otherwise
* gcc main.c yields:
* /tmp/ccJMhzM7.o: In function `main':
* main.c:(.text+0x17b): undefined reference to `copy_file_range'
* collect2: error: ld returned 1 exit status
*/
#include <stdlib.h>
#include <stdio.h>
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <fcntl.h>
static loff_t
copy_file_range(int fd_in, loff_t *off_in, int fd_out,
loff_t *off_out, size_t len, unsigned int flags) {
return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags);
}
int main( int argc, char *argv[] ) {
const char *msg = NULL;
int dst_fd = -1;
int src_fd = -1;
if( argc < 3 ) {
printf( "%s <srcfile> <dstfile>\n", argv[0] );
return EXIT_FAILURE;
}
do {
const char *srcfile = argv[1];
const char *tmpfile = argv[2];
struct stat info;
// Following seems to be a write test.
dst_fd = open(tmpfile, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666);
if( dst_fd == -1 ) {
msg = "open-ing dst #1";
}
close( dst_fd );
dst_fd = -1;
src_fd = open( srcfile, O_RDONLY|O_CLOEXEC );
if( src_fd == -1 ) {
msg = "open-ing src";
break;
}
if( fstat( src_fd, &info ) == -1 ) {
msg = "fstat-ing src";
break;
}
dst_fd = open(tmpfile, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0100700);
if( dst_fd == -1 ) {
msg = "open-ing dst #2";
break;
}
if( fchmod(dst_fd, 0100700) == -1 ) {
msg = "fchmod-ing dst";
break;
}
if( copy_file_range( src_fd, NULL, dst_fd, NULL, info.st_size, 0) == -1 ) {
msg = "copy_file_range";
}
} while( 0 );
if( dst_fd >= 0 ) {
close(dst_fd);
}
if( src_fd >= 0 ) {
close(src_fd);
}
if( msg ) {
perror( msg );
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
} |
The test needs to exercise the rust code that rustup calls, not the glibc
code directly.
…On Fri, 23 Oct 2020, 15:35 Raj, ***@***.***> wrote:
Sure and done. When I run the program inlined below I get the expected:
copy_file_range: Operation not supported
Other possibly pertinent facts:
1. rpm -a glibc reports glibc-2.17-307.el7.1.x86_64 on the host with
the trouble, so my glibc is well before the 2.27 that exports
copy_file_range, but the kernel is ostensibly new enough.
2. my login filesystem is an NFS mount of what I believe, but am not
sure, is a WIndohs file server.
/** * This program tests availability of copy_file_range on a system described * by uname -a: * Linux solu 3.10.0-1127.19.1.el7.x86_64 #1 SMP Tue Aug 25 17:23:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux * * It was modeled on the following strace log: * * open("/research/users/rogerk/.rustup/tmp/e934jgtdi1tk6h56_file", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 4 * close(4) = 0 * lstat("/research/users/rogerk/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/components", {st_mode=S_IFREG|0700, st_size=212, ...}) = 0 * open("/research/users/rogerk/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/components", O_RDONLY|O_CLOEXEC) = 4 * fstat(4, {st_mode=S_IFREG|0700, st_size=212, ...}) = 0 * open("/research/users/rogerk/.rustup/tmp/e934jgtdi1tk6h56_file", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0100700) = 10 * fstat(10, {st_mode=S_IFREG|0700, st_size=0, ...}) = 0 * fchmod(10, 0100700) = 0 * copy_file_range(4, NULL, 10, NULL, 212, 0) = -1 EOPNOTSUPP (Operation not supported) * close(10) = 0 * close(4) = 0 * * Note that I have to define the syscall locally because otherwise * gcc main.c yields: * /tmp/ccJMhzM7.o: In function `main': * main.c:(.text+0x17b): undefined reference to `copy_file_range' * collect2: error: ld returned 1 exit status */
#include <stdlib.h>
#include <stdio.h>
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <fcntl.h>
static loff_tcopy_file_range(int fd_in, loff_t *off_in, int fd_out,
loff_t *off_out, size_t len, unsigned int flags) {
return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags);
}
int main( int argc, char *argv[] ) {
const char *msg = NULL;
int dst_fd = -1;
int src_fd = -1;
if( argc < 3 ) {
printf( "%s <srcfile> <dstfile>\n", argv[0] );
return EXIT_FAILURE;
}
do {
const char *srcfile = argv[1];
const char *tmpfile = argv[2];
struct stat info;
// Following seems to be a write test.
dst_fd = open(tmpfile, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666);
if( dst_fd == -1 ) {
msg = "open-ing dst #1";
}
close( dst_fd );
dst_fd = -1;
src_fd = open( srcfile, O_RDONLY|O_CLOEXEC );
if( src_fd == -1 ) {
msg = "open-ing src";
break;
}
if( fstat( src_fd, &info ) == -1 ) {
msg = "fstat-ing src";
break;
}
dst_fd = open(tmpfile, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0100700);
if( dst_fd == -1 ) {
msg = "open-ing dst #2";
break;
}
if( fchmod(dst_fd, 0100700) == -1 ) {
msg = "fchmod-ing dst";
break;
}
if( copy_file_range( src_fd, NULL, dst_fd, NULL, info.st_size, 0) == -1 ) {
msg = "copy_file_range";
}
} while( 0 );
if( dst_fd >= 0 ) {
close(dst_fd);
}
if( src_fd >= 0 ) {
close(src_fd);
}
if( msg ) {
perror( msg );
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2472 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADZ7XTHWPZXIOGUWB7L2JTSMGBCHANCNFSM4QPU4GEQ>
.
|
|
Because as I linked earlier in #2472 (comment) , rust is meant to automatically handle that call failing and fallback. We know the syscall is failing - thats not interesting. What is interesting is whether the fallback code is working or if the fallback code is failing ; if it is working thensomething else - like for example you've got readonly files in rustup's work area - is causing the issue. We can discriminate if a testcase using the rust wrapper of that codepath on some known good files fails. I'm not trying to deny the problem or make you jump through hoops - I'm trying to discriminate between issues we can help you directly with, and issues that you'll need to work with the rust team on (e.g. the fallback code that I linked you to failing). That said, it looks like master has changed - see https://github.com/rust-lang/rust/blob/9abf81afa8c20ea48c8515dc4bbc714118502f5e/library/std/src/sys/unix/fs.rs#L1235 now - so I think this will get fixed soon, but we'll need to build rustup with this, and I'm not sure if its in a release etc yet. |
Ah, ok, the first (fallback) part wasn't clear to me...in which case I'm not sure how to interpret @kinnison 's suggestion. ...extract the relevant fallback code from rustup and run that? I can do pretty much anything you suggest. |
I don't think anything is needed - ENOTSUPP is clearly added to the nightly library; if you wanted a working rustup for yourself you could build rustup from source using nightly and it should all just work from that point on. |
Ok. I'll give that a try. |
The commit which properly introduces the ENOTSUPP is rust-lang/rust@1316c78 which was the 12th August. In theory there's been enough time since then that the next rustup release ought to include it. So it would be very useful if you can confirm if building a rustup with current stable fixes it, or if it needs nightly. If you clone rustup and run Good luck. |
No joy, from either path. (builds of several crates failed ) |
Hi @biork I'm interested in seeing if this is still the case with the new (1.23) rustup. Could you have another go for me? (Sorry for the ongoing pain) D. |
I just did a clean install using the...
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
...method, and, yes, it worked.
…On Thu, Dec 03, 2020 at 1:17pm Daniel Silverstone ***@***.***> wrote:
Hi @biork
I'm interested in seeing if this is still the case with the new (1.23)
rustup. Could you have another go for me? (Sorry for the ongoing pain)
D.
-- You are receiving this because you were mentioned. Reply to this email
directly or view it on GitHub:
#2472 (comment)
|
Wonderful, thank you. I'm going to close this issue, but ping either here or on a fresh issue if problems recur. |
Using rustup version 1.22.1
"rustup update" fails and rolls back with the error message:
error: count not copy file from...
The source and destination don't matter. I straced it and found the failure happens in a copy_file_range system call which is somewhat new. I'm running on Linux 3.10 with glibc 2.17. The system call triggers an EOPNOTSUPP error.
This problem has been attributed to NFS in other bug reports. May or may not be related to NFS, though I don't believe it is.
Clearly copy_file_range is related, and given that that's a newer system call, explains the problem on an old Linux.
Steps
Possible Solution(s)
The copy_file_range() system call first appeared in Linux 4.5, but glibc 2.27 provides a user-space emulation when it is not available.
Build rustup on the oldest possible Linux installation.
Notes
Output of
rustup --version
:rustup 1.22.1 (b01adbb 2020-07-08)
Output of
rustup show
:Default host: x86_64-unknown-linux-gnu
rustup home: /research/users/rogerk/.rustup
stable-x86_64-unknown-linux-gnu (default)
rustc 1.41.0 (5e1a79984 2020-01-27)
The text was updated successfully, but these errors were encountered: