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
Closed

Regression 9.2.1.0 File#mv #5415

ahorek opened this issue Nov 6, 2018 · 6 comments
Milestone

Comments

@ahorek
Copy link
Contributor

@ahorek ahorek 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
Copy link
Contributor Author

@ahorek ahorek 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
Copy link
Member

@headius headius 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
Copy link
Member

@headius headius 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
Copy link
Member

@headius headius 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
Copy link
Contributor Author

@ahorek ahorek 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
Copy link
Member

@headius headius 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
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants