← 输入框|github.com|刷新
Skip to content

Regression 9.2.1.0 File#mv #5415

Closed
Closed

Description

@ahorek

Environment

jruby 9.2.1.0-SNAPSHOT (2.5.0) 2018-11-05 d4e5bb6 Java HotSpot(TM) 64-Bit Server VM 25.191-b12 on 1.8.0_191-b12 +jit [linux-x86_64]
Linux DESKTOP-2POPPQP 4.4.0-17134-Microsoft #345-Microsoft Wed Sep 19 17:47:00 PST 2018 x86_64 x86_64 x86_64 GNU/Linux

Expected Behavior

require 'fileutils'

FileUtils.touch('/tmp/test')
FileUtils.mv('/tmp/test', '/home/ahorek/test2')

Actual Behavior

       12: from /home/ahorek/.rvm/rubies/jruby-head/bin/irb:13:in `<main>'
       11: from org/jruby/RubyKernel.java:1181:in `catch'
       10: from org/jruby/RubyKernel.java:1181:in `catch'
        9: from org/jruby/RubyKernel.java:1415:in `loop'
        8: from org/jruby/RubyKernel.java:1043:in `eval'
        7: from (irb):10:in `evaluate'
        6: from /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/stdlib/fileutils.rb:516:in `mv'
        5: from /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/stdlib/fileutils.rb:1556:in `fu_each_src_dest'
        4: from /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/stdlib/fileutils.rb:1574:in `fu_each_src_dest0'
        3: from /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/stdlib/fileutils.rb:1558:in `block in fu_each_src_dest'
        2: from /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/stdlib/fileutils.rb:527:in `block in mv'
        1: from org/jruby/RubyFile.java:1113:in `rename'
IOError (/tmp/test -> /home/ahorek/test2: Odkaz mezi zařízeními není přípustný)

FileUtils.mv('/tmp/test', '/tmp/test2') works fine. It fails only if I try to move something into my home folder /home/ahorek

originally found because bundler stopped working

IOError: /tmp/bundler-compact-index-20181106-3006-8kj95u/versions -> /home/ahorek/.bundle/cache/compact_index/rubygems.org.443.29b0360b937aa4d161703e6160654e47/versions: Odkaz mezi zařízeními není přípustný
  org/jruby/RubyFile.java:1113:in `rename'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/vendor/fileutils/lib/fileutils.rb:469:in `block in mv'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/vendor/fileutils/lib/fileutils.rb:1461:in `block in fu_each_src_dest'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/vendor/fileutils/lib/fileutils.rb:1477:in `fu_each_src_dest0'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/vendor/fileutils/lib/fileutils.rb:1459:in `fu_each_src_dest'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/vendor/fileutils/lib/fileutils.rb:458:in `mv'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/compact_index_client/updater.rb:72:in `block in update'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/shared_helpers.rb:118:in `filesystem_access'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/compact_index_client/updater.rb:71:in `block in update'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/stdlib/tmpdir.rb:89:in `mktmpdir'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/compact_index_client/updater.rb:31:in `update'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/compact_index_client.rb:82:in `update'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/compact_index_client.rb:69:in `update_and_parse_checksums!'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/fetcher/compact_index.rb:69:in `available?'
  org/jruby/RubyMethod.java:129:in `call'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/fetcher/compact_index.rb:16:in `block in available?'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/fetcher.rb:158:in `use_api'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/source/rubygems.rb:382:in `block in api_fetchers'
  org/jruby/RubyArray.java:2653:in `select'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/source/rubygems.rb:382:in `api_fetchers'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/source/rubygems.rb:387:in `block in remote_specs'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/index.rb:11:in `build'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/source/rubygems.rb:386:in `remote_specs'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/source/rubygems.rb:89:in `specs'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/definition.rb:273:in `block in index'
  org/jruby/RubyArray.java:1789:in `each'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/definition.rb:271:in `block in index'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/index.rb:11:in `build'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/definition.rb:268:in `index'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/definition.rb:258:in `resolve'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/definition.rb:170:in `specs'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/definition.rb:158:in `resolve_remotely!'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/installer.rb:310:in `resolve_if_needed'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/installer.rb:84:in `block in run'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/process_lock.rb:12:in `block in lock'
  org/jruby/RubyIO.java:1154:in `open'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/process_lock.rb:9:in `lock'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/installer.rb:73:in `run'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/installer.rb:25:in `install'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/cli/update.rb:61:in `run'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/cli.rb:280:in `update'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/cli.rb:27:in `dispatch'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/cli.rb:18:in `start'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/exe/bundle:30:in `block in <main>'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/lib/bundler/friendly_errors.rb:124:in `with_friendly_errors'
  /home/ahorek/.rvm/rubies/jruby-head/lib/ruby/gems/shared/gems/bundler-1.17.1/exe/bundle:22:in `<main>'
  org/jruby/RubyKernel.java:1000:in `load'
  /home/ahorek/.rvm/gems/jruby-head/bin/bundle:23:in `<main>'

related #5356

Activity

  1. ahorek commented on Nov 6, 2018

    @ahorek
    ContributorAuthor

    ok, it works with sudo, but jruby 9.2.0.0 or MRI works even WITHOUT sudo, this is the reason:

    ATOMIC_MOVE : The move is performed as an atomic file system operation and all other options are ignored. If the target file exists then it is implementation specific if the existing file is replaced or this method fails by throwing an IOException. If the move cannot be performed as an atomic file system operation then AtomicMoveNotSupportedException is thrown. This can arise, for example, when the target location is on a different FileStore and would require that the file be copied, or target location is associated with a different provider to this object.

    I quickely tried to use

    Files.move(oldPath, destPath);
    

    as a fallback, the file was moved successfuly, but then it failed at this line
    Errno::EACCES (Permission denied)
    https://github.com/jruby/jruby/pull/5356/files#diff-faed2f52be1f32aabe75bca4deab250dL1124

    I'll investigate more tomorrow

  2. headius commented on Nov 6, 2018

    @headius
    Member

    The error is not unexpected; on many Linux distributions, /tmp is mounted to a different device than the rest of the system. FileUtils.mv would normally rescue the error and fall back on a less secure way to move files, but unfortunately we raise the wrong one (IOError instead of EXDEV).

    The problem is that on your system, the error message for this "cross-device link" is in Czech. We're (unfortunately) using the text of the message to know that we should re-raise the IOException from Java as EXDEV.

    I'm not sure how to proceed here. Will have to see if there's any other way to determine the cause of the error.

  3. headius commented on Nov 6, 2018

    @headius
    Member

    @ahorek Files.move should work for you if you specify other than ATOMIC_MOVE. That's what causes it to reject moves across devices, since it can't be done atomically.

  4. headius commented on Nov 6, 2018

    @headius
    Member

    Aha, we may be in luck. If I'm reading the JDK sources properly, it is actually raising a subclass of IOException, AtomicMoveNotSupportedException. That would be a more robust way to detect this, if indeed it is what JDK is raising. I don't suppose you're available right now to help test?

  5. added a commit that references this issue on Nov 6, 2018
    745be77
  6. ahorek commented on Nov 6, 2018

    @ahorek
    ContributorAuthor

    hi @headius yes

    Files.move(oldPath, destPath, StandardCopyOption.ATOMIC_MOVE)
    

    throws AtomicMoveNotSupportedException
    which is rescued as IOException

    } catch (IOException ioe) {
                throw Helpers.newIOErrorFromException(runtime, ioe);
    
  7. headius commented on Nov 6, 2018

    @headius
    Member
  8. added this to the JRuby 9.2.1.0 milestone on Nov 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions