Почему символические ссылки в /proc/$PID/fd/ действуют как жесткие ссылки?

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

Файлы в /proc/$PID/fd/ отображаются в виде символических ссылок, но они позволяют вам получить доступ к содержимому удаленной цели, как описано здесь: Восстановление удаленных файлов Linux с помощьюlsof,

Как это работает? Почему он отображается как символическая ссылка, если он не действует как единое целое? Является ли это символьной реализацией файловой системы proc, которая хранит ссылку на индекс файла?

1 ответ

Если его цель удалена, объект в /proc/$PID/fd/ отображается как неработающая символическая ссылка при использовании ls(1) или же file(1), но он действительно действует иначе, когда открывается open(2),

На моем Debian 9 я использовал strace(1) чтобы увидеть, что происходит, когда я пытаюсь прочитать символическую ссылку. Команда sudo strace cat "$symlink", Соответствующая строка из stderr

  • либо ок

    open("$symlink", O_RDONLY)                   = 3
    
  • или же ENOENT

    open("$symlink", O_RDONLY)                   = -1 ENOENT (No such file or directory)
    

(примечание: я не говорю, что это все возможные результаты open(2) в общем).

Результаты, достижения:

               | regular symlink | /proc/$PID/fd/$N |
---------------+-----------------+------------------+
exists, valid  |       OK        |        OK        |
exists, broken |     ENOENT      |        OK        | <- the difference
doesn't exist  |     ENOENT      |      ENOENT      |
---------------+-----------------+------------------+

Я также узнал, что когда я бегу file "$symlink"это вызывает lstat(2), readlink(2) а также stat(2), Это системные вызовы, основанные на путях, а не файловые дескрипторы. Если символическая ссылка существует (действительная или неработающая), open(2) никогда не вызывается, чтобы открыть его или его цель. ENOENT от stat(2) указывает на то, что ссылка не работает.

Мой вывод таков: "неработающая ссылка" - это свойство, полученное из результатов некоторых системных вызовов; но когда вы открываете ссылку из /proc/$PID/fd/, open(2) просто знает, что с ним делать, и не заботится о том, что даст другой инструмент.

Обратите внимание на весь /proc только подделывает "нормальную" файловую систему. Несколько причуд:

  • Файлы могут иметь динамическое содержимое, но они не изменяются с помощью системных вызовов (попробуйте inotifywait).
  • Объекты могут (не) появляться, но они не создаются и не удаляются с помощью системных вызовов (снова inotifywait).
  • В некотором смысле объекты могут не существовать, пока вы не будете взаимодействовать с ними. Бежать bash и подожди несколько минут. взывать ls -l /proc/$$/fd чтобы увидеть его файловые дескрипторы. Вероятно, ctimes покажет "этот самый момент". Тем не менее, если вы будете повторять команду каждые несколько секунд, вы заметите, что время никогда не изменится. (Мелочи: сначала я, хотя я мог бы ответить на этот вопрос. Определить, как долго файл был открыт с stat и символические ссылки в /proc/$PID/fd/ но я был неправ; теперь ты знаешь почему).

Неудивительно, что эти символические ссылки, о которых вы спрашиваете, в некоторых случаях не ведут себя как обычные символические ссылки. Целиком /proc был разработан, чтобы вести себя несколько иначе. Я полагаю open(2) была сознательно предоставлена ​​возможность воспользоваться этим.

Другие вопросы по тегам