На файл в данной файловой системе ссылается его индексный узел, он же inode. Пока есть ссылки на этот inode, будь то на диске (связанный с именем файла (ов), может существовать несколько раз) или "в памяти" (дескриптор открытого файла aka fd, точка монтирования, mmaped ...) файл и его данные остаются на диске. Когда на него больше нет ссылок, он действительно удаляется, а пространство освобождается. Когда ссылка на диск становится 0, даже если есть ссылки "в памяти", невозможно связать его новым именем, потому что для пользователя нет API ядра, позволяющего, например, связать инод, на который ссылается его fd или Само значение inode, оно доступно только по имени файла (если только в адекватной файловой системе не используется темная и опасная магия: 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
с параметром --sparse=always
является хорошим выбором, если файл диска виртуальной машины был "ленивым" и в основном пустым, чтобы использовать меньше места.