Может ли файл быть извлечен его inode?

Я выполнил следующие команды в указанном порядке:

$ln a b
$ls -i a b
523669 a 523669 b
$rm -f a
$ls -i b
523669 b

В результате этого теста я пришел к выводу, что команда rm фактически удаляет только имя файла (a в этом тесте) вместо файла, поскольку inode все еще существует и может быть извлечен через другое имя файла (b)

Мой вопрос: если файл жестко связан только с одним именем файла, когда в файл выполняется rm, это реальный файл (т. е. inode) полностью удалены? И если нет, может ли файл inode быть извлечен без имени файла и только через inode?

25 голосов | спросил user43312 29 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowSun, 29 Sep 2013 11:07:07 +0400 2013, 11:07:07

3 ответа


25

Если вы попытаетесь открыть файл через свой inode, это обходит любой обход каталога. Обход каталога необходим для определения разрешений файла и каталогов, ведущих к нему. Без обхода каталога ядро ​​не может определить, разрешен ли вызывающему процессу доступ к файлу.

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

В Linux (и, возможно, в других вариантах unix по той же причине) вы не можете создать ссылку на удаленный файл, поэтому, если файл больше не имеет имени, вы не можете его повторно добавить. откройте удаленный файл, открыв магические ссылки в /proc/$pid/fd/.

Если файл больше не имеет ссылки и больше не открыт, он больше не существует, и пространство, ранее использовавшееся его данными, может быть восстановлено в любое время.

¹ Возможно, вы сможете сделать это, покрутив байты непосредственно в файловой системе зависимым от файловой системы способом, например, с помощью debugfs для ext2 /ext3 /ext4. Для этого требуется доступ к устройству, на котором установлена ​​файловая система (т. Е. Как правило, только root может попробовать его). Однако, хотя debugfs могут обращаться к файлу с помощью inode, это не помогает, если файл будет удален: файл будет действительно удален, если приложение закроет его, а запуск debugfs в режиме чтения-записи на смонтированной файловой системе - это рецепт для катастрофа. Суб>

ответил Gilles 30 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 30 Sep 2013 05:04:22 +0400 2013, 05:04:22
11

В Linux, debugfs , интерактивный отладчик файловой системы ext2 /ext3 /ext4 предоставляет ln, которая может принимать номер inode как filespec и создавать новую жесткую ссылку на соответствующий файл. На практике это требует, чтобы несвязанный файл оставался открытым процессом , поддерживая дескриптор открытого файла в /proc/[pid]/fd/[n]. Попытка этого удалить в удаленном файле, скорее всего, приведет к повреждению файловой системы.

Это связано с тем, что для обеспечения того, чтобы ext3 (и в ext ext4) мог безопасно возобновить разблокировку после сбоя, он фактически нули из указателей блоков в inode , в то время как ext2 просто отмечает эти блоки как неиспользуемые в битовых рамах блока и отмечает индекс inode как «удаляется» и оставляет указатели блоков в покое. Тем не менее, поскольку файловая система должна быть смонтирована для чтения и записи для создания жесткой ссылки, блоки, зарезервированные для удаленного файла, могут быть уже перераспределены.

До версии ядра 2.6.39 раньше было ln -L|--logical опция, введенная в GNU coreutils v8.0 , можно использовать для восстановления несвязанного файла через дескриптор открытого файла в /proc/[pid]/fd/[n] if как несвязанный файл, так и новый hardlink размещены на tmpfs . С тех пор эта возможность была отключено , из-за того, что Gilles указал на соображения безопасности, связанные с возможностью создания жесткой ссылки непосредственно из дескриптора файла.

ответил Thomas Nyman 29 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowSun, 29 Sep 2013 11:59:47 +0400 2013, 11:59:47
2

Вопрос может быть принят теоретически (что может быть достигнуто с помощью debugfs) или прагматически (аварийная ситуация). В последнем случае я предполагаю, что цель - сохранить день и восстановить содержимое файла, возможно, в срочном порядке (так я приземлился по этому вопросу, поэтому считаю, что он по-прежнему актуальен и полезен).

Поскольку API ядра не существует, debugfs не должен запускаться в живой файловой системе, потому что он напрямую управляет структурой FS. Поэтому, чтобы сделать это вживую, вы должны получить другое имя файла. Предполагая, что файл по-прежнему открыт каким-то процессом (любым процессом), можно найти для удобных файловых дескрипторов в /proc:

$ lsof -F pf "$PWD/a" | sed 's/^p//' # find pid and file descriptor number of any process having the file open
$ pid=1234
$ ls -l /proc/$pid/fd/* | grep "$PWD/a" # find file descriptor number
$ fd=42
$ cat /proc/$pid/fd/$fd > "$PWD/a.restored" # read contents to a new filename

Советы:

  • Если у вас есть сомнения относительно правильного fd, вы можете запускать такие команды, как file
  • если в файл записана процедура, обязательно остановите этот процесс как можно скорее или вы не получите последние данные. Трюк (непроверенный) может заключаться в том, чтобы открыть файл, считанный только через fd, с каким-либо другим процессом (попробуйте tail -f > /proc/$pid/fd/$fd > /dev/null, выйдите из процесса записи, чтобы что он выходит из строя и использует fd нового процесса.
ответил Lloeki 7 AM000000100000002731 2017, 10:53:27

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132