MINA SSHD
  1. MINA SSHD
  2. SSHD-100

[sftp] open(2) w/ O_CREAT|O_TRUNC works, but O_CREAT alone fails

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 0.6.0
    • Labels:
      None

      Description

      Hi folks,

      I've mounted an sftp directory using sshfs like so:

      1. sshfs -d -p 9022 bpowers@$SERVER_NAME:/bpowers /home/bpowers/Desktop/wintest

      The following sequences of commands shows the problem:
      root@bpowers-laptop:/home/bpowers/Desktop/wintest/test# rm -f bar
      root@bpowers-laptop:/home/bpowers/Desktop/wintest/test# touch bar
      touch: cannot touch `bar': No such file or directory
      root@bpowers-laptop:/home/bpowers/Desktop/wintest/test# echo "foo" > bar
      root@bpowers-laptop:/home/bpowers/Desktop/wintest/test# cat bar
      foo
      root@bpowers-laptop:/home/bpowers/Desktop/wintest/test# rm bar
      root@bpowers-laptop:/home/bpowers/Desktop/wintest/test# touch bar
      touch: cannot touch `bar': No such file or directory
      ...

      I've reduced it to a simple test case. Running the attached program gives me the following:
      root@bpowers-laptop:/home/bpowers/Desktop/wintest/test# /home/bpowers/creat_test
      /home/bpowers/Desktop/wintest/test/abc2: No such file or directory
      /home/bpowers/Desktop/wintest/test/abc3: worked.

      The difference is in the flags passed to open(2), and the consequence of this is that I cannot use cp or rsync to create any files over sftp (although they will update existing files).

      see attachment for the source of creat_test, which can be compiled with:
      $ gcc -o creat_test test.c
      and
      $ man 2 open
      for a description of the flags.

      Debugging output from sshfs shows the following:

      unique: 39, opcode: LOOKUP (1), nodeid: 1, insize: 45
      LOOKUP /test
      getattr /test
           NODEID: 2
           unique: 39, success, outsize: 144
      unique: 40, opcode: LOOKUP (1), nodeid: 2, insize: 45
      LOOKUP /test/abc2
      getattr /test/abc2
           unique: 40, error: -2 (No such file or directory), outsize: 16
      unique: 41, opcode: CREATE (35), nodeid: 2, insize: 61
      create flags: 0x8041 /test/abc2 0100644 umask=0022
           unique: 41, error: -2 (No such file or directory), outsize: 16

      unique: 42, opcode: LOOKUP (1), nodeid: 2, insize: 45
      LOOKUP /test/abc3
      getattr /test/abc3
           unique: 42, error: -2 (No such file or directory), outsize: 16
      unique: 43, opcode: CREATE (35), nodeid: 2, insize: 61
      create flags: 0x8241 /test/abc3 0100644 umask=0022
           create[25271456] flags: 0x8241 /test/abc3
      fgetattr[25271456] /test/abc3
           NODEID: 4
           unique: 43, success, outsize: 160
      unique: 44, opcode: FLUSH (25), nodeid: 4, insize: 64
      flush[25271456]
           unique: 44, success, outsize: 16
      unique: 45, opcode: RELEASE (18), nodeid: 4, insize: 64
      release[25271456] flags: 0x8001
           unique: 45, success, outsize: 16

        Activity

        Hide
        Guillaume Nodet added a comment -

        Thankx a ton for this patch!

        Show
        Guillaume Nodet added a comment - Thankx a ton for this patch!
        Hide
        Guillaume Nodet added a comment -

        Committing to https://svn.apache.org/repos/asf/mina/sshd/trunk ...
        M sshd-core/src/main/java/org/apache/sshd/server/SshFile.java
        M sshd-core/src/main/java/org/apache/sshd/server/filesystem/NativeSshFile.java
        M sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
        Committed r1043378

        Show
        Guillaume Nodet added a comment - Committing to https://svn.apache.org/repos/asf/mina/sshd/trunk ... M sshd-core/src/main/java/org/apache/sshd/server/SshFile.java M sshd-core/src/main/java/org/apache/sshd/server/filesystem/NativeSshFile.java M sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java Committed r1043378
        Hide
        Bobby Powers added a comment -

        sshfs does (using version 3 of the protocol):

        [00018] OPEN
        [00019] LSTAT
        [00018] HANDLE 49bytes (312083ms)
        [00019] STATUS 31bytes (976315ms)

        the open succeeds, because line 410 of SftpSubsyem only checks to make sure the SshFile is writable if it doesn't exist before returning a handle. The lstat fails because SftpSubsystem.writeAttrs(Buffer, SshFile, int) calls doesExist() on the SshFile immediately afterwards, finds out it doesn't exist, and throws an IOException.

        I think the sensible thing to do is on OPEN, call create() on the SshFile if appropriate. Patch attached.

        Show
        Bobby Powers added a comment - sshfs does (using version 3 of the protocol): [00018] OPEN [00019] LSTAT [00018] HANDLE 49bytes (312083ms) [00019] STATUS 31bytes (976315ms) the open succeeds, because line 410 of SftpSubsyem only checks to make sure the SshFile is writable if it doesn't exist before returning a handle. The lstat fails because SftpSubsystem.writeAttrs(Buffer, SshFile, int) calls doesExist() on the SshFile immediately afterwards, finds out it doesn't exist, and throws an IOException. I think the sensible thing to do is on OPEN, call create() on the SshFile if appropriate. Patch attached.
        Hide
        Bobby Powers added a comment -

        I'm willing to take a stab with it monday or tuesday, but since I'm completely unfamiliar with the codebase I'd appreciate any pointers you folks can give.

        Show
        Bobby Powers added a comment - I'm willing to take a stab with it monday or tuesday, but since I'm completely unfamiliar with the codebase I'd appreciate any pointers you folks can give.
        Hide
        Guillaume Nodet added a comment -

        Do you think you could write a patch for that?

        Show
        Guillaume Nodet added a comment - Do you think you could write a patch for that?
        Hide
        Bobby Powers added a comment -

        Jira ate the debugging output (you might want to edit this message or view source for better indentation):

        unique: 39, opcode: LOOKUP (1), nodeid: 1, insize: 45
        LOOKUP /test
        getattr /test
        NODEID: 2
        unique: 39, success, outsize: 144
        unique: 40, opcode: LOOKUP (1), nodeid: 2, insize: 45
        LOOKUP /test/abc2
        getattr /test/abc2
        unique: 40, error: -2 (No such file or directory), outsize: 16
        unique: 41, opcode: CREATE (35), nodeid: 2, insize: 61
        create flags: 0x8041 /test/abc2 0100644 umask=0022
        unique: 41, error: -2 (No such file or directory), outsize: 16

        unique: 42, opcode: LOOKUP (1), nodeid: 2, insize: 45
        LOOKUP /test/abc3
        getattr /test/abc3
        unique: 42, error: -2 (No such file or directory), outsize: 16
        unique: 43, opcode: CREATE (35), nodeid: 2, insize: 61
        create flags: 0x8241 /test/abc3 0100644 umask=0022
        create[25271456] flags: 0x8241 /test/abc3
        fgetattr[25271456] /test/abc3
        NODEID: 4
        unique: 43, success, outsize: 160
        unique: 44, opcode: FLUSH (25), nodeid: 4, insize: 64
        flush[25271456]
        unique: 44, success, outsize: 16
        unique: 45, opcode: RELEASE (18), nodeid: 4, insize: 64
        release[25271456] flags: 0x8001
        unique: 45, success, outsize: 16

        Show
        Bobby Powers added a comment - Jira ate the debugging output (you might want to edit this message or view source for better indentation): unique: 39, opcode: LOOKUP (1), nodeid: 1, insize: 45 LOOKUP /test getattr /test NODEID: 2 unique: 39, success, outsize: 144 unique: 40, opcode: LOOKUP (1), nodeid: 2, insize: 45 LOOKUP /test/abc2 getattr /test/abc2 unique: 40, error: -2 (No such file or directory), outsize: 16 unique: 41, opcode: CREATE (35), nodeid: 2, insize: 61 create flags: 0x8041 /test/abc2 0100644 umask=0022 unique: 41, error: -2 (No such file or directory), outsize: 16 unique: 42, opcode: LOOKUP (1), nodeid: 2, insize: 45 LOOKUP /test/abc3 getattr /test/abc3 unique: 42, error: -2 (No such file or directory), outsize: 16 unique: 43, opcode: CREATE (35), nodeid: 2, insize: 61 create flags: 0x8241 /test/abc3 0100644 umask=0022 create [25271456] flags: 0x8241 /test/abc3 fgetattr [25271456] /test/abc3 NODEID: 4 unique: 43, success, outsize: 160 unique: 44, opcode: FLUSH (25), nodeid: 4, insize: 64 flush [25271456] unique: 44, success, outsize: 16 unique: 45, opcode: RELEASE (18), nodeid: 4, insize: 64 release [25271456] flags: 0x8001 unique: 45, success, outsize: 16

          People

          • Assignee:
            Guillaume Nodet
            Reporter:
            Bobby Powers
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development