You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Gary Gregory (JIRA)" <ji...@apache.org> on 2017/10/26 15:59:00 UTC

[jira] [Resolved] (VFS-589) SFTP moveTo operation hangs if the server does not support SSH channelExec.

     [ https://issues.apache.org/jira/browse/VFS-589?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Gary Gregory resolved VFS-589.
------------------------------
       Resolution: Fixed
    Fix Version/s: 2.2.1

Here is what's new in {{SftpFileSystemConfigBuilder}}:

I added:
- {{setConnectTimeoutMillis(FileSystemOptions, Integer)}} and a getter.
- {{setSessionTimeoutMillis(FileSystemOptions, Integer)}} and a getter.

I deprecated 
- {{setTimeout(FileSystemOptions, Integer)}} and the getter in favor of {{setSessionTimeoutMillis(FileSystemOptions, Integer)}}

The default behavior has NOT changed.

This let's you get set a connection timeout AND/OR a session timeout.

Please verify and close or comment.

Thank you.

> SFTP moveTo operation hangs if the server does not support SSH channelExec.
> ---------------------------------------------------------------------------
>
>                 Key: VFS-589
>                 URL: https://issues.apache.org/jira/browse/VFS-589
>             Project: Commons VFS
>          Issue Type: Bug
>    Affects Versions: Nightly Builds
>            Reporter: L
>             Fix For: 2.2.1
>
>         Attachments: patch_sftp_tests_hang_no_exec.diff, patch_sftp_timeouts.diff
>
>
> In our case the server was explicitly configured to disable SSH channelExec.
> Our code was hanging trying to execute moveTo(). Stacktrace:
> {code}
>    java.lang.Thread.State: TIMED_WAITING (on object monitor)
>     at java.lang.Object.wait(Native Method)
>     at java.io.PipedInputStream.read(PipedInputStream.java:326)
>     - locked <0x00000006a7a184d0> (a com.jcraft.jsch.Channel$MyPipedInputStream)
>     at java.io.PipedInputStream.read(PipedInputStream.java:377)
>     - locked <0x00000006a7a184d0> (a com.jcraft.jsch.Channel$MyPipedInputStream)
>     at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
>     at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
>     at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
>     - locked <0x00000006a7a184b8> (a java.io.InputStreamReader)
>     at java.io.InputStreamReader.read(InputStreamReader.java:184)
>     at org.apache.commons.vfs2.provider.sftp.SftpFileSystem.executeCommand(SftpFileSystem.java:328)
>     at org.apache.commons.vfs2.provider.sftp.SftpFileSystem.getGroupsIds(SftpFileSystem.java:260)
>     at org.apache.commons.vfs2.provider.sftp.SftpFileObject.getPermissions(SftpFileObject.java:317)
>     at org.apache.commons.vfs2.provider.sftp.SftpFileObject.doIsWriteable(SftpFileObject.java:357)
>     at org.apache.commons.vfs2.provider.AbstractFileObject.isWriteable(AbstractFileObject.java:1791)
>     at org.apache.commons.vfs2.impl.DecoratedFileObject.isWriteable(DecoratedFileObject.java:229)
>     at org.apache.commons.vfs2.cache.OnCallRefreshFileObject.isWriteable(OnCallRefreshFileObject.java:156)
>     at org.apache.commons.vfs2.provider.AbstractFileObject.moveTo(AbstractFileObject.java:1857)
>     at org.apache.commons.vfs2.impl.DecoratedFileObject.moveTo(DecoratedFileObject.java:241)
>     at org.apache.commons.vfs2.cache.OnCallRefreshFileObject.moveTo(OnCallRefreshFileObject.java:184)
> ...
> {code}
> Technically the connection was alive because the session had a configured timeout and the jcraft code kept sending keepalive SSH_MSG_GLOBAL_REQUEST messages, but the thread performing FileObject.moveTo() did not return from moveTo().
> I have changed SftpProviderTestCase to reproduce the problem: testRenameFile() hangs.
> The patch (patch_sftp_tests_hang_no_exec.diff) is attached.
> I traced the problem to the fact that VFS invokes method com.jcraft.jsch.Channel.connect(). This method uses timeout value 0, in which case class com.jcraft.jsch.ChannelExec creates an instance of class com.jcraft.jsch.RequestExec that sends an SSH packet SSH_MSG_CHANNEL_REQUEST with "want reply" set to 0.
> Correspondingly, if the server supports SSH channelExec, it executes the specified command and returns some data.
> But if the server *does not* support SSH channelExec it sends nothing back while jcraft code tries to read something. This is the hang I am observing.
> The fix would be to invoke com.jcraft.jsch.Channel.connect(int connectTimeout).
> As a result jcraft sends an SSH packet SSH_MSG_CHANNEL_REQUEST with "want reply" set to 1 *and* it waits for an answer *and* it reacts to the answer.
> Correspondingly, if the server supports SSH channelExec, it sends an SSH packet SSH_MSG_CHANNEL_SUCCESS and the executes the specified command and returns some data.
> If the server *does not* support SSH channelExec it sends an SSH packet SSH_MSG_CHANNEL_FAILURE.
> jcraft reacts on either of this messages because if waits for one of them. If it receives SSH_MSG_CHANNEL_SUCCESS it goes further and reads the response of the executed command.
> If it receives SSH_MSG_CHANNEL_FAILURE it immediately reports this by throwing JSchException with message "failed to send channel request".
> There is no hang whatsoever. Instead all tests from ProviderRenameTests fail with errors like
> {code}
> Could not determine if file "sftp://testtest@localhost:50036/write-tests" is writeable.
> {code}
> The test suite actually hangs at the end, but this is caused by https://issues.apache.org/jira/browse/VFS-588
> I have patched VFS classes to always open jcraft's channels with timeouts. In addition the patch always sets some default timeout value on jcraft's session if none was configured via SftpFileSystemConfigBuilder.
> Patch is also attached:  patch_sftp_timeouts.diff



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)