4

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

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

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

1 ответ1

2

Если его цель удалена, сущность в /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) сознательно получил возможность воспользоваться этим.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .