From 68034f3fb240e170ed1c9565b369fc017178777c Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 14 Aug 2013 17:49:59 +0200 Subject: [PATCH] fix very slow sftp upload to localhost --- ...-window_size-explicit-adjustments-on.patch | 69 +++++++++++++++++++ libssh2-1.4.2-utf8.patch | 2 +- libssh2.spec | 9 ++- 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 0004-partially-revert-window_size-explicit-adjustments-on.patch diff --git a/0004-partially-revert-window_size-explicit-adjustments-on.patch b/0004-partially-revert-window_size-explicit-adjustments-on.patch new file mode 100644 index 0000000..fe7751a --- /dev/null +++ b/0004-partially-revert-window_size-explicit-adjustments-on.patch @@ -0,0 +1,69 @@ +From 9e56b84c41efcaf3349f82a93c3dc854e172e5c4 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 9 Aug 2013 16:22:08 +0200 +Subject: [PATCH 4/5] partially revert "window_size: explicit adjustments only" + +This partially reverts commit 03ca9020756a4e16f0294e5b35e9826ee6af2364 +in order to fix extreme slowdown when uploading to localhost via SFTP. + +I was able to repeat the issue on RHEL-7 on localhost only. It did not +occur when uploading via network and it did not occur on a RHEL-6 box +with the same version of libssh2. + +The problem was that sftp_read() used a read-ahead logic to figure out +the window_size, but sftp_packet_read() called indirectly from +sftp_write() did not use any read-ahead logic. +--- + src/channel.c | 29 +++++++++++++++++++++++++++++ + 1 files changed, 29 insertions(+), 0 deletions(-) + +diff --git a/src/channel.c b/src/channel.c +index 4f41e1f..d4ffdce 100644 +--- a/src/channel.c ++++ b/src/channel.c +@@ -1759,6 +1759,15 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, + channel->read_state = libssh2_NB_state_created; + } + ++ /* ++ * =============================== NOTE =============================== ++ * I know this is very ugly and not a really good use of "goto", but ++ * this case statement would be even uglier to do it any other way ++ */ ++ if (channel->read_state == libssh2_NB_state_jump1) { ++ goto channel_read_window_adjust; ++ } ++ + rc = 1; /* set to >0 to let the while loop start */ + + /* Process all pending incoming packets in all states in order to "even +@@ -1867,6 +1876,26 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, + more off the network again */ + channel->read_state = libssh2_NB_state_created; + ++ if(channel->remote.window_size < (LIBSSH2_CHANNEL_WINDOW_DEFAULT*30)) { ++ /* the window is getting too narrow, expand it! */ ++ ++ channel_read_window_adjust: ++ channel->read_state = libssh2_NB_state_jump1; ++ /* the actual window adjusting may not finish so we need to deal with ++ this special state here */ ++ rc = _libssh2_channel_receive_window_adjust(channel, ++ (LIBSSH2_CHANNEL_WINDOW_DEFAULT*60), 0, NULL); ++ if (rc) ++ return rc; ++ ++ _libssh2_debug(session, LIBSSH2_TRACE_CONN, ++ "channel_read() filled %d adjusted %d", ++ bytes_read, buflen); ++ /* continue in 'created' state to drain the already read packages ++ first before starting to empty the socket further */ ++ channel->read_state = libssh2_NB_state_created; ++ } ++ + return bytes_read; + } + +-- +1.7.1 + diff --git a/libssh2-1.4.2-utf8.patch b/libssh2-1.4.2-utf8.patch index aa1e854..9177691 100644 --- a/libssh2-1.4.2-utf8.patch +++ b/libssh2-1.4.2-utf8.patch @@ -3,7 +3,7 @@ --- libssh2/NEWS +++ libssh2/NEWS -@@ -3284,7 +3284,7 @@ Simon Josefsson (16 Nov 2009) +@@ -3552,7 +3552,7 @@ Simon Josefsson (16 Nov 2009) - support arcfour128 cipher per RFC 4345 Daniel Stenberg (21 Oct 2009) diff --git a/libssh2.spec b/libssh2.spec index 63ce2a0..c485e67 100644 --- a/libssh2.spec +++ b/libssh2.spec @@ -12,7 +12,7 @@ Name: libssh2 Version: 1.4.3 -Release: 7%{?dist} +Release: 8%{?dist} Summary: A library implementing the SSH2 protocol Group: System Environment/Libraries License: BSD @@ -22,6 +22,7 @@ Patch0: libssh2-1.4.2-utf8.patch Patch1: 0001-sftp-seek-Don-t-flush-buffers-on-same-offset.patch Patch2: 0002-sftp-statvfs-Along-error-path-reset-the-correct-stat.patch Patch3: 0003-sftp-Add-support-for-fsync-OpenSSH-extension.patch +Patch4: 0004-partially-revert-window_size-explicit-adjustments-on.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -nu) BuildRequires: openssl-devel BuildRequires: zlib-devel @@ -80,6 +81,9 @@ sed -i s/4711/47%{?__isa_bits}/ tests/ssh2.{c,sh} %patch2 -p1 %patch3 -p1 +# http://thread.gmane.org/gmane.network.ssh.libssh2.devel/6428 +%patch4 -p1 + # Make sshd transition appropriately if building in an SELinux environment %if !(0%{?fedora} >= 17 || 0%{?rhel} >= 7) chcon $(/usr/sbin/matchpathcon -n /etc/rc.d/init.d/sshd) tests/ssh2.sh || : @@ -146,6 +150,9 @@ rm -rf %{buildroot} %{_libdir}/pkgconfig/libssh2.pc %changelog +* Wed Aug 14 2013 Kamil Dudka 1.4.3-8 +- fix very slow sftp upload to localhost + * Sat Aug 03 2013 Fedora Release Engineering - 1.4.3-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild