Иногда люди удаляют файлы, которые им не следует, при длительном процессе файл остается открытым, и данные восстанавливаются путем /proc/<pid>/fd/N
просто недостаточно круто. Было бы неплохо, если бы вы могли «отменить» удаление, запустив некую волшебную опцию для ln, которая позволила бы вам повторно привязать к номеру inode (восстановлен с помощью lsof).
Я не могу найти никаких инструментов Linux для этого, по крайней мере, с помощью беглого поиска в Google.
Что у вас, serverfault?
EDIT1: причина загрузки файла из /proc/<pid>/fd/N
недостаточно круто, потому что процесс, у которого все еще открыт файл, все еще пишет в него. Удаление удаляет ссылку на индексный дескриптор из пространства имен файловой системы. Я хочу способ воссоздать ссылку.
EDIT2: «debugfs ln» работает, но риск слишком высок, поскольку он блокирует необработанные данные файловой системы. Восстановленный файл также безумно несовместим. Количество ссылок равно нулю, и я не могу добавлять к нему ссылки. Мне так хуже, так как я могу просто использовать /proc/<pid>/fd/N
для доступа к данным, не повреждая мою фс.
Было бы неплохо, если бы вы могли «отменить» удаление, запустив некую волшебную опцию для ln, которая позволила бы вам повторно привязать к номеру inode (восстановлен с помощью lsof).
Эта удивительность была представлена ln
в v8.0 (GNU / coreutils) с -L|--logical
вариант, который вызывает ln
разыменовать /proc/<pid>/fd/<handle>
первый. Так что простой
ln -L /proc/<pid>/fd/<handle> /path/to/deleted/file
достаточно, чтобы повторно связать удаленный файл.
Похоже, вы уже многое поняли, поэтому я не буду вдаваться в подробности. Есть несколько способов найти индексный дескриптор, и обычно вы можете выполнить cat и перенаправить STDOUT. Ты можешь использовать debugfs
. Выполните эту команду в:
ln <$INODE> FILENAME
Убедитесь, что у вас есть резервные копии файловой системы. Возможно, после этого вам потребуется запустить fsck. Я успешно протестировал это с inode, который все еще записывается, и он действительно работает, чтобы создать новую жесткую ссылку на разыменованный inode.
Если файл не связан с неоткрытым файлом в ext3, данные будут потеряны. Я не уверен, насколько это верно, но большая часть моего опыта восстановления данных связана с ext2. Из FAQ по ext3:
В: Как я могу восстановить (восстановить) удаленные файлы с моего раздела ext3? Собственно, нельзя! Вот что об этом сказал один из разработчиков Андреас Дилгер:
Чтобы гарантировать, что ext3 может безопасно возобновить разъединение после сбоя, он фактически обнуляет указатели блоков в индексном дескрипторе, тогда как ext2 просто отмечает эти блоки как неиспользуемые в битовых картах блоков и отмечает индексный дескриптор как «удаленный» и оставляет блок только указатели.
Ваша единственная надежда - "grep" найти части ваших файлов, которые были удалены, и надеяться на лучшее.
В этом вопросе также есть соответствующая информация:
Я перезаписал большой файл пустым на сервере linux. Могу ли я восстановить существующий файл?
способ 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 проще и работает так же хорошо, поэтому я предпочитаю это.
Я не знаю, как сделать именно то, что вы хотите, но я бы сделал следующее:
Не идеально, конечно, но возможно. Другой вариант - поиграться с debugfs (используя link
command), но на производственной машине это немного страшно!
Сегодня столкнулся с той же проблемой. Лучшее, что я мог придумать, это бежать
% tail -n +0 -f /proc/<pid>/fd/<fd> /path/to/deleted_file
в сеансе tmux / screen до завершения процесса.
Интересный вопрос. Интервьюер задал мне тот же вопрос на собеседовании. Я сказал ему, что это нелегкий способ сделать это, и в целом он не стоит затраченного времени и усилий. Я действительно спросил его, что, по его мнению, можно решить этой проблемой ...
Использовать Сыщик icat.
sudo icat /dev/rdisk1s2 5484287 > accidentally_deleted_open_file
Быстрое решение, которое сработало для меня, без устрашающих инструментов:
1) найдите процесс + fd, посмотрев прямо в / proc:
ls -al /proc/*/fd/* 2>/dev/null | grep {filename}
2) Затем метод, аналогичный @ nickray, с pv
добавлено:
tail -c +0 -f /proc/{procnum}/fd/{fdnum} | pv -s {expectedsize} > {recovery_filename}
По завершении вам может потребоваться Ctrl-C (ls /proc/{procnum}/fd/{fdnum}
сообщит вам, что файл больше не существует)), но если вы знаете точный размер в байтах, вы можете использовать pv -S
чтобы он вышел, когда будет достигнут счет.