Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression 9.2.1.0 File#mv #5415

Closed
ahorek opened this Issue Nov 6, 2018 · 6 comments

Comments

Projects
None yet
2 participants
@ahorek
Copy link
Contributor

commented Nov 6, 2018

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

@ahorek

This comment has been minimized.

Copy link
Contributor Author

commented Nov 6, 2018

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

@headius

This comment has been minimized.

Copy link
Member

commented Nov 6, 2018

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.

@headius

This comment has been minimized.

Copy link
Member

commented Nov 6, 2018

@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.

@headius

This comment has been minimized.

Copy link
Member

commented Nov 6, 2018

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?

headius added a commit to headius/jruby that referenced this issue Nov 6, 2018

@ahorek

This comment has been minimized.

Copy link
Contributor Author

commented Nov 6, 2018

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);
@headius

This comment has been minimized.

Copy link
Member

commented Nov 6, 2018

@ahorek See #5416!

@headius headius closed this in 7b14404 Nov 6, 2018

@headius headius added this to the JRuby 9.2.1.0 milestone Nov 6, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.