Повторная привязка удаленного файла

Повторная привязка удаленного файла

Иногда люди удаляют файлы, которые не должны были, долго выполняющийся процесс все еще держит файл открытым, и восстановление данных с помощью catting /proc/<pid>/fd/Nпросто недостаточно круто. Достаточно круто, если бы вы могли "отменить" удаление, запустив какую-нибудь волшебную опцию в ln, которая позволила бы вам повторно связать его с номером inode (восстановленным с помощью lsof).

Я не могу найти никаких инструментов Linux, позволяющих это сделать, по крайней мере, с помощью беглого поиска в Google.

Что у тебя, серверфоул?

EDIT1: Причина, по которой catting файла /proc/<pid>/fd/Nне достаточно крут, заключается в том, что процесс, который все еще держит файл открытым, все еще пишет в него. Удаление удаляет ссылку на inode из пространства имен файловой системы. Мне нужен способ повторного создания ссылки.

EDIT2: 'debugfs ln' работает, но риск слишком высок, так как он загружает необработанные данные файловой системы. Восстановленный файл также безумно непоследователен. Количество ссылок равно нулю, и я не могу добавлять ссылки на него. Мне так хуже, так как я могу просто использовать /proc/<pid>/fd/Nдля доступа к данным, не повреждая свою fs.

решение1

Было бы здорово, если бы можно было «отменить» удаление, запустив какую-нибудь волшебную опцию ln, которая позволила бы вам повторно установить ссылку на номер inode (восстановленный с помощью lsof).

Эта удивительность была представлена ln​​вверсия 8.0(GNU/coreutils) с -L|--logicalопцией, которая вызывает lnразыменование /proc/<pid>/fd/<handle>первого. Так что простое

ln -L /proc/<pid>/fd/<handle> /path/to/deleted/file

достаточно для повторной ссылки на удаленный файл.

решение2

Похоже, вы уже многое поняли, поэтому я не буду вдаваться в излишние подробности. Есть несколько методов поиска inode, и обычно вы можете использовать cat и перенаправить STDOUT. Вы можете использоватьdebugfs. Выполните эту команду в:

ln <$INODE> FILENAME

Убедитесь, что у вас есть резервные копии файловой системы. Вероятно, вам понадобится запустить fsck после этого. Я успешно протестировал это с inode, в который все еще велась запись, и это действительно работает для создания новой жесткой ссылки на разыменованный inode.

Если файл не связан с неоткрытым файлом в ext3, данные теряются. Я не уверен, насколько это верно, но большая часть моего опыта восстановления данных связана с ext2. Из часто задаваемых вопросов по ext3:

В: Как мне восстановить (отменить удаление) удаленные файлы с моего раздела ext3? На самом деле, вы не можете! Вот что сказал об этом один из разработчиков, Андреас Дилгер:

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

Ваша единственная надежда — выполнить команду grep для поиска частей удаленных файлов и надеяться на лучшее.

В этом вопросе также есть соответствующая информация:

Я перезаписал большой файл пустым на сервере Linux. Могу ли я восстановить существующий файл?

решение3

способ debugfs, как вы видели, на самом деле не работает, и в лучшем случае ваш файл будет автоматически удален (из-за журнала) после перезагрузки, а в худшем вы можете испортить свою файловую систему, что приведет к «циклу смерти перезагрузки». Правильное решение (TM) — выполнить восстановление на уровне VFS (что также имеет дополнительное преимущество работы практически со всеми текущими файловыми системами Linux). Способ системного вызова (flink) отбрасывался каждый раз, когда он появлялся в LKML, поэтому лучший способ — через модуль + ioctl.

Проект, реализующий этот подход и имеющий достаточно небольшой и чистый код, — fdlink (https://github.com/pkt/fdlink.gitдля версии, протестированной с ядром ubuntu maverick). С его помощью, после вставки модуля (sudo insmod flink_dev.ko), вы можете просто выполнить "./flinkapp /proc//fd/X /my/link/path", и он сделает именно то, что вам нужно.

Вы также можете использовать перенесенную версию vfs-undelete.sourceforge.net, которая также работает (и может автоматически перенаправляться на исходное имя), но код fdlink проще и работает так же хорошо, поэтому я предпочитаю именно ее.

решение4

Я не знаю, как именно сделать то, что вы хотите, но я бы сделал следующее:

  • Открыть файл RO из другого процесса
  • Дождитесь завершения исходного процесса.
  • Скопируйте данные из вашего открытого ФД в файл

Не идеально, конечно, но возможно. Другой вариант — поиграться с debugfs (используя команду link), но это немного страшно на рабочей машине!

Связанный контент