[ 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)