Debian 8.9 восстанавливает удаленные, но заблокированные файлы

347
SevenOfNine

Я случайно запустил rm -R / home /. Моя домашняя папка содержала несколько дисков виртуальных машин, которые использовались в данный момент. Я также получил ошибку, что некоторые файлы не могли быть удалены. Тем не менее, я больше не могу получить доступ к файлам в моей папке / home /.

В поисках решения я обнаружил, что могу попытаться восстановить файлы с помощью cp / proc / PID / fd / 12 / target /.

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

Будут ли у меня несоответствия на этих дисках? Или у тебя может быть есть другой намек?

Я ценю любую помощь!

Большое спасибо!

0
Нет, указанный метод должен быть файловым: в системах POSIX дескриптор открытого файла считается ссылкой (ссылкой) на файл, поэтому пространство, занимаемое таким файлом, остается в файловой системе без изменений; у него просто нет имен в самой файловой системе для доступа к нему. kostix 6 лет назад 1
Вы можете открыть вторую ссылку на безымянный файл (например: `sleep 99999 </ proc / PID / fd / 12 &`), чтобы избежать его удаления, а затем заморозить или остановить виртуальную машину, чтобы убедиться в отсутствии несоответствий в резервной копии cp , Конечно, если вы остановите ВМ, ошибка не допускается после (и до: в команде, используемой для сохранения ссылки) A.B 6 лет назад 1
Спасибо за этот отличный совет! Я скопировал несколько виртуальных машин без второй ссылки и приостановки, а некоторые с помощью описанного вами метода. Оба метода работали нормально, хотя некоторые машины должны были восстанавливать некоторые блоки с помощью журнала во время загрузки. Возможно, потому что были записи во время копирования файла. Тем не менее, я мог восстановить все VirtualMachines. @AB, если хотите, вы можете написать ответ, чтобы я мог пометить его как таковой. Спасибо за помощь!! SevenOfNine 6 лет назад 0
Готово, добавлен ответ, с некоторыми пояснениями A.B 6 лет назад 1

1 ответ на вопрос

1
A.B

На файл в данной файловой системе ссылается его индексный узел, он же inode . Пока есть ссылки на этот inode, будь то на диске (связанный с именем файла (ов), может существовать несколько раз) или "в памяти" (дескриптор открытого файла aka fd, точка монтирования, mmaped ...) файл и его данные остаются на диске. Когда на него больше нет ссылок, он действительно удаляется, а пространство освобождается. Когда ссылка на диск становится 0, даже если есть ссылки «в памяти», невозможно связать его новым именем, потому что для пользователя нет API ядра, позволяющего, например, связать инод, на который ссылается его fd или само значение индексного дескриптора, он доступен только по имени файла (если на адекватную файловой системе, используя темную и опасную магию : debugfs ln).

Ядро Linux все еще предоставляет некоторые возможности для доступа к этому файлу с помощью /procпсевдофайловой системы. Каждый открытый файл отображается в виде символической ссылки, указывающей на файл. Имя файла является косметической информацией (и может быть неправильным, когда файл был несвязанным), но сам файл должна рассматриваться как на реальный файл, как показан в ядре./proc/PID/fd/

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

cp --sparse=always /proc/PID/fd/12 > backup,

Поскольку виртуальная машина работает, это может привести к противоречивым результатам: файловая система (внутри файла) может измениться во время копирования и стать непоследовательной и поврежденной. Так что либо заморозьте ВМ, если ее гипервизор разрешает это и не закрывает файл диска ВМ в замороженном состоянии, либо добавьте новую ссылку на безымянный файл и остановите ВМ. Если вы не хотите рисковать, добавьте ссылку, прежде чем заморозить ее. Любая команда, считывающая файл и продолжающаяся достаточно долго, вполне подойдет. Например:

$ sleep 99999 < /proc/PID/fd/12 & [1] 12087 

Теперь вы должны проверить, что /proc/12087/fd/0ссылается на тот же ... (deleted)файл.

Виртуальная машина теперь может быть заморожена или даже остановлена ​​(но затем не сможет запуститься снова). Поскольку в файловой системе больше нет активности, резервное копирование должно быть согласованным (с восстановлением журнала файловой системы, если оно просто заморожено). Использование cpс параметром with --sparse=alwaysявляется хорошим выбором, если файл диска виртуальной машины был «ленивым» и в основном пустым, чтобы использовать меньше места.

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