IOException: Отказано в доступе при закрытии потока файла - PullRequest
0 голосов
/ 06 июня 2018

На удаленной машине я обнаружил исключение, которое я не могу воспроизвести или объяснить.

Один и тот же процесс работал без проблем в течение многих лет.Несколько похожих файлов загружаются из SCP в общую сетевую папку в RedHat Linux, на диске обязательно есть свободное место, и все разрешения в порядке.Есть только несколько открытых файловых дескрипторов.Сегодня неожиданно при записи последнего файла было java.io.IOException: Permission denied, а закрывает поток, но файл был сохранен правильно.

Каковы возможные причины такого исключения? Я не нашел ничего в исходном коде Java, кроме сопоставления Permission denied с EACCES.Просматривая интернет, я обнаруживал только случаи, когда люди получали Permission denied при открытии потока, но не закрывали его.

java.io.IOException: Permission denied
  at java.io.FileOutputStream.close0(Native Method)
  at java.io.FileOutputStream.access$000(FileOutputStream.java:53)
  at java.io.FileOutputStream$1.close(FileOutputStream.java:356)
  at java.io.FileDescriptor.closeAll(FileDescriptor.java:212)
  at java.io.FileOutputStream.close(FileOutputStream.java:354)
  at java.io.FilterOutputStream.close(FilterOutputStream.java:159)
  at com.aestasit.ssh.dsl.ScpMethods.doGet(ScpMethods.groovy:249)
  at com.aestasit.ssh.dsl.ScpMethods.this$2$doGet(ScpMethods.groovy)
  at com.aestasit.ssh.dsl.ScpMethods.download(ScpMethods.groovy:162)
  at com.aestasit.ssh.dsl.SshDslEngine.executeSession(SshDslEngine.groovy:70)
  at com.aestasit.ssh.dsl.SshDslEngine$remoteSession.call(Unknown Source)
  at com.aestasit.ssh.DefaultSsh.remoteSession(DefaultSsh.groovy:46)
  at com.aestasit.ssh.DefaultSsh$remoteSession.callStatic(Unknown Source)

1 Ответ

0 голосов
/ 06 июня 2018

Это всего лишь теория ....

Глядя на исходный код ядра Linux, кажется, что при некоторых обстоятельствах системный вызов close(fd) пытается выполнить внутреннюю очистку перед закрытием.Если fd был связан с файлом в «файловой системе», где можно было изменить действующие разрешения на доступ, когда файл был открыт, то вполне возможно, что сбрасывание при закрытии может завершиться неудачей, поскольку текущие разрешения слишком ограничительныЭто может превратиться в сбой системного вызова EACCES.

Такой сбой встречается редко, потому что разрешение файла изменяться как раз в «правильное» время, чтобы вызвать сбой;то есть между системным вызовом close и предыдущими системными вызовами write.

Кроме того, возможно, что это произойдет только для определенных типов файлов;например, файлы на удаленном файловом сервере, где удаленный сервер реализует управление доступом.


Обратите внимание, что сбой close() с EACCES не предусмотрен ручным вводом Linux или спецификациями POSIX.Документы подразумевают, что доступ проверяется только при открытии файла, это (по крайней мере) неожиданное поведение.

Однако обратная сторона заключается в том, что различные аспекты поведения (виртуальной) файловой системы зависят от реализации самих файловых систем.И есть несколько случаев, когда файловые системы не ведут себя "нормально".

...