Dropped nodelay workaround

This was a performance improvement for SSH versions prior to
4.4. There is no reason to continue to support this.
This commit is contained in:
Nikolaus Rath 2017-06-06 10:57:09 -04:00
parent af1f3c6235
commit 132dd88755
5 changed files with 5 additions and 202 deletions

View File

@ -2,8 +2,9 @@ Unreleased Changes
------------------
* Added support for more SSH options.
* Dropped support for the *nodelay* workaround.
Release 2.9 (2017-04-17)
------------------------

View File

@ -15,8 +15,8 @@ sshfs_CFLAGS = $(SSHFS_CFLAGS)
sshfs_CPPFLAGS = -D_REENTRANT -DFUSE_USE_VERSION=26 -DLIBDIR=\"$(libdir)\" \
-DIDMAP_DEFAULT="\"$(IDMAP_DEFAULT)\""
EXTRA_DIST = sshnodelay.c sshfs.1.in
CLEANFILES = sshnodelay.so sshfs.1 sshfs.1.tmp
EXTRA_DIST = sshfs.1.in
CLEANFILES = sshfs.1 sshfs.1.tmp
dist_man_MANS = sshfs.1
@ -26,17 +26,3 @@ sshfs.1: sshfs.1.in
-e 's,__UNMOUNT_COMMAND__,$(UNMOUNT_COMMAND),g' \
<$(srcdir)/sshfs.1.in >sshfs.1.tmp || exit 1; \
mv sshfs.1.tmp sshfs.1
if SSH_NODELAY_SO
all-local: sshnodelay.so
install-exec-local: sshnodelay.so
test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
$(INSTALL) -m 755 sshnodelay.so "$(DESTDIR)$(libdir)/sshnodelay.so"
uninstall-local:
rm -f "$(DESTDIR)$(libdir)/sshnodelay.so"
sshnodelay.so:
$(CC) -Wall -W -s --shared -fPIC $(sshnodelay_libs) sshnodelay.c -o sshnodelay.so
endif

View File

@ -8,8 +8,6 @@ AM_PROG_CC_C_O
CFLAGS="$CFLAGS -Wall -W"
LIBS=
AC_SEARCH_LIBS(dlsym, [dl])
sshnodelay_libs=$LIBS
AC_SUBST(sshnodelay_libs)
LIBS=
case "$target_os" in
@ -18,31 +16,6 @@ case "$target_os" in
*) osname=unknown;;
esac
AC_ARG_ENABLE(sshnodelay,
[ --disable-sshnodelay Don't compile NODELAY workaround for ssh])
if test -z "$enable_sshnodelay"; then
AC_MSG_CHECKING([OpenSSH version])
[eval `ssh -V 2>&1 | sed -n 's/^OpenSSH_\([1-9][0-9]*\)\.\([0-9][0-9]*\).*/ssh_major=\1 ssh_minor=\2/p'`]
if test "x$ssh_major" != x -a "x$ssh_minor" != x; then
if test $ssh_major -gt 4 -o \( $ssh_major = 4 -a $ssh_minor -ge 4 \); then
AC_MSG_RESULT([$ssh_major.$ssh_minor >= 4.4, disabling NODELAY workaround])
enable_sshnodelay=no
else
AC_MSG_RESULT([$ssh_major.$ssh_minor < 4.4, enabling NODELAY workaround])
enable_sshnodelay=yes
fi
else
AC_MSG_RESULT([not found])
fi
fi
if test "$enable_sshnodelay" = "yes"; then
AC_DEFINE(SSH_NODELAY_WORKAROUND, 1, [Compile ssh NODELAY workaround])
fi
AM_CONDITIONAL(SSH_NODELAY_SO, test "$enable_sshnodelay" = "yes")
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
PKG_CHECK_MODULES([SSHFS], [fuse >= 2.3 glib-2.0 gthread-2.0])
have_fuse_opt_parse=no

98
sshfs.c
View File

@ -132,8 +132,6 @@
#define SFTP_SERVER_PATH "/usr/lib/sftp-server"
#define SSHNODELAY_SO "sshnodelay.so"
/* Asynchronous readdir parameters */
#define READDIR_START 2
#define READDIR_MAX 32
@ -216,7 +214,6 @@ struct sshfs {
struct fuse_args ssh_args;
char *workarounds;
int rename_workaround;
int nodelay_workaround;
int nodelaysrv_workaround;
int truncate_workaround;
int buflimit_workaround;
@ -423,21 +420,17 @@ static struct fuse_opt sshfs_opts[] = {
static struct fuse_opt workaround_opts[] = {
SSHFS_OPT("none", rename_workaround, 0),
SSHFS_OPT("none", nodelay_workaround, 0),
SSHFS_OPT("none", nodelaysrv_workaround, 0),
SSHFS_OPT("none", truncate_workaround, 0),
SSHFS_OPT("none", buflimit_workaround, 0),
SSHFS_OPT("none", fstat_workaround, 0),
SSHFS_OPT("all", rename_workaround, 1),
SSHFS_OPT("all", nodelay_workaround, 1),
SSHFS_OPT("all", nodelaysrv_workaround, 1),
SSHFS_OPT("all", truncate_workaround, 1),
SSHFS_OPT("all", buflimit_workaround, 1),
SSHFS_OPT("all", fstat_workaround, 1),
SSHFS_OPT("rename", rename_workaround, 1),
SSHFS_OPT("norename", rename_workaround, 0),
SSHFS_OPT("nodelay", nodelay_workaround, 1),
SSHFS_OPT("nonodelay", nodelay_workaround, 0),
SSHFS_OPT("nodelaysrv", nodelaysrv_workaround, 1),
SSHFS_OPT("nonodelaysrv", nodelaysrv_workaround, 0),
SSHFS_OPT("truncate", truncate_workaround, 1),
@ -892,85 +885,6 @@ static void ssh_add_arg(const char *arg)
_exit(1);
}
#ifdef SSH_NODELAY_WORKAROUND
static int do_ssh_nodelay_workaround(void)
{
#ifdef __APPLE__
char *oldpreload = getenv("DYLD_INSERT_LIBRARIES");
#else
char *oldpreload = getenv("LD_PRELOAD");
#endif
char *newpreload;
char sopath[PATH_MAX];
int res;
#ifdef __APPLE__
char *sshfs_program_path_base = NULL;
if (!sshfs_program_path[0]) {
goto nobundle;
}
sshfs_program_path_base = dirname(sshfs_program_path);
if (!sshfs_program_path_base) {
goto nobundle;
}
snprintf(sopath, sizeof(sopath), "%s/%s", sshfs_program_path_base,
SSHNODELAY_SO);
res = access(sopath, R_OK);
if (res == -1) {
goto nobundle;
}
goto pathok;
nobundle:
#endif /* __APPLE__ */
snprintf(sopath, sizeof(sopath), "%s/%s", LIBDIR, SSHNODELAY_SO);
res = access(sopath, R_OK);
if (res == -1) {
char *s;
if (!realpath(sshfs.progname, sopath))
return -1;
s = strrchr(sopath, '/');
if (!s)
s = sopath;
else
s++;
if (s + strlen(SSHNODELAY_SO) >= sopath + sizeof(sopath))
return -1;
strcpy(s, SSHNODELAY_SO);
res = access(sopath, R_OK);
if (res == -1) {
fprintf(stderr, "sshfs: cannot find %s\n",
SSHNODELAY_SO);
return -1;
}
}
#ifdef __APPLE__
pathok:
#endif
newpreload = g_strdup_printf("%s%s%s",
oldpreload ? oldpreload : "",
oldpreload ? " " : "",
sopath);
#ifdef __APPLE__
if (!newpreload || setenv("DYLD_INSERT_LIBRARIES", newpreload, 1) == -1)
fprintf(stderr, "warning: failed set DYLD_INSERT_LIBRARIES for ssh nodelay workaround\n");
#else /* !__APPLE__ */
if (!newpreload || setenv("LD_PRELOAD", newpreload, 1) == -1) {
fprintf(stderr, "warning: failed set LD_PRELOAD "
"for ssh nodelay workaround\n");
}
#endif /* __APPLE__ */
g_free(newpreload);
return 0;
}
#endif
static int pty_expect_loop(void)
{
@ -1104,14 +1018,6 @@ static int start_ssh(void)
} else if (pid == 0) {
int devnull;
#ifdef SSH_NODELAY_WORKAROUND
if (sshfs.nodelay_workaround &&
do_ssh_nodelay_workaround() == -1) {
fprintf(stderr,
"warning: ssh nodelay workaround disabled\n");
}
#endif
if (sshfs.nodelaysrv_workaround) {
int i;
/*
@ -3433,9 +3339,6 @@ static void usage(const char *progname)
" none no workarounds enabled\n"
" all all workarounds enabled\n"
" [no]rename fix renaming to existing file (default: off)\n"
#ifdef SSH_NODELAY_WORKAROUND
" [no]nodelay set nodelay tcp flag in ssh (default: on)\n"
#endif
" [no]nodelaysrv set nodelay tcp flag in sshd (default: off)\n"
" [no]truncate fix truncate for old servers (default: off)\n"
" [no]buflimit fix buffer fillup bug in server (default: on)\n"
@ -3973,7 +3876,6 @@ int main(int argc, char *argv[])
/* SFTP spec says all servers should allow at least 32k I/O */
sshfs.max_read = 32768;
sshfs.max_write = 32768;
sshfs.nodelay_workaround = 1;
sshfs.nodelaysrv_workaround = 0;
#ifdef __APPLE__
sshfs.rename_workaround = 1;

View File

@ -1,59 +0,0 @@
#define _GNU_SOURCE
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
/* Wrapper around connect(2) to explicitly set TCP_NODELAY. */
static int nodelay_connect(
int (*real_connect)(int, const struct sockaddr *, socklen_t),
int sock, const struct sockaddr *addr, socklen_t addrlen)
{
int res = real_connect(sock, addr, addrlen);
if (!res && addr->sa_family == AF_INET) {
int opt = 1;
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
}
return res;
}
#if __APPLE__
/* OS X does not have LD_PRELOAD but has DYLD_INSERT_LIBRARIES. The right
* environment variable is set by sshfs.c when attempting to load the
* sshnodelay workaround.
*
* However, things are not that simple: DYLD_INSERT_LIBRARIES does not
* behave exactly like LD_PRELOAD. Instead, the dyld dynamic linker will
* look for __DATA __interpose sections on the libraries given via the
* DYLD_INSERT_LIBRARIES variable. The contents of this section are pairs
* of replacement functions and functions to be replaced, respectively.
* Prepare such section here. */
int custom_connect(int sock, const struct sockaddr *addr, socklen_t addrlen);
typedef struct interpose_s {
void *new_func;
void *orig_func;
} interpose_t;
static const interpose_t interposers[] \
__attribute__ ((section("__DATA, __interpose"))) = {
{ (void *)custom_connect, (void *)connect },
};
int custom_connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
{
return nodelay_connect(connect, sock, addr, addrlen);
}
#else /* !__APPLE__ */
int connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
{
return nodelay_connect(dlsym(RTLD_NEXT, "connect"),
sock, addr, addrlen);
}
#endif /* !__APPLE__ */