-
Notifications
You must be signed in to change notification settings - Fork 490
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
mv fails with EPERM when moving a file between different remote FS's #100
Comments
Here's a workaround implemented as an LD_PRELOAD library. /* preload_rename.c: LD_PRELOAD library to make rename() fail only with EXDEV
* make: gcc -fPIC -shared -opreload_rename.so preload_rename.c -ldl
* run: LD_PRELOAD=$(pwd)/preload_rename.so command
*/
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <errno.h>
/* Function pointer to the value of the glibc function */
int (*real_rename)(const char *oldpath, const char *newpath) = NULL;
/* Wrapping function */
int rename(const char *oldpath, const char *newpath)
{
int rc;
/* resolve and call the real function from glibc */
real_rename = dlsym(RTLD_NEXT, "rename");
rc = real_rename(oldpath, newpath);
/* set errno to EXDEV to incite file managers to try to actually move the
* file */
if (rc < 0) errno = EXDEV;
return(rc);
} |
Thanks for the report! You are right, the EXDEV error should come from the OpenSSH server and then be forwarded all the way to the mv command. Not sure why it isn't working. First steps to debug this would be to figure out what OpenSSH actually returns. |
Isn't the return status from OpenSSH given in its log: "status 4" "sent status Failure"? Or do you think that another layer mingles the data? |
I don't know. You could start from the assumption that OpenSSH does return the right value, and then try to determine why SSHFS doesn't forward that to the kernel. |
Moving files on a same sshfs mount but between different FS's on the
remote host fails. The server is OpenSSH 7.4p1-10+deb9u1 from Debian
with default config (sftp-server enabled). The sshfs command is also
used with the default options; note that the option workaround=rename
does not change this error case:
Relevant output of the sftp-server DEBUG3 log in /var/log/auth.log:
Moving on the remote works as expected:
Here the error code returned by rename(3) is EXDEV which makes mv
attempt to actually move the data. I wonder why POSIX does not allow
mv(1posix) to attempt a move after other kinds of failure. What other
similar command is able to force a move of data in this case (while
preserving times and attributes) that is simpler to type than:
bash -c 'cp -a "$@" && rm "${@:1:$#-1}"' arg0
I suppose that sshfs returns EPERM instead of EXDEV because sftp does
not return a significant error code. Would this be by design of sftp or
a shortcoming of OpenSSH's sftp-server?
As a fix maybe sshfs could always return EXDEV when rename fails and it
does not know precisely which error was triggered. Or does sftp by
chance make it possible to detect mount points?
Regards
The text was updated successfully, but these errors were encountered: