You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "L (JIRA)" <ji...@apache.org> on 2015/11/30 11:36:10 UTC

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

L created VFS-589:
---------------------

             Summary: 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


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.3.4#6332)