Куда идут дескрипторы открытых файлов, когда они умирают?

15

Что происходит с файлами, которые удаляются, когда у них открыт дескриптор файла?

Я думал об этом с тех пор, как понял, что могу удалить видеофайл, пока он воспроизводился в MPlayer, и он все равно будет проигрываться до конца. Откуда он берет данные? Это все еще идет с жесткого диска? Это было скопировано в RAM после того, как я удалил файл?

Если он все еще находится на жестком диске, что произойдет, если я заполняю файловую систему, когда программа выполняет чтение из фактически нераспределенного пространства? Если он буферизируется в ОЗУ, что произойдет, если я очисту буферы?

Что произойдет, если файл был в общей папке NFS - хранится ли он на сервере? (Разве это не угроза безопасности - DoS тоннами открытых удаленных файловых дескрипторов?)

Выполнение lsof -n |grep '(deleted)'иногда дает интересные результаты; если я обновляю пакеты, которые заменяют файлы общих библиотек, тогда запущенные программы, которые использовали эти библиотеки, все равно смогут использовать их, как будто ничего не изменилось.

Бонусный вопрос: есть ли способ вернуть данные из мертвых в этой ситуации?

amphetamachine
источник

Ответы:

13

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

debugfs и аналогичные инструменты могут быть использованы для восстановления содержимого inode.

Игнасио Васкес-Абрамс
источник
10
Это правильно, однако, если файл все еще открыт, вы можете получить его обратно, перейдя в / proc / <PID> / fd, где PID - это pid программы, в которой файл все еще открыт. Этот каталог содержит все открытые файловые дескрипторы программы, и вы можете обращаться к ним, как к обычным файлам, поэтому вы можете создать жесткую ссылку для «восстановления» файла.
Патрик
Обратите внимание, что /procэто специфично для Linux (как есть debugfs).
Игнасио Васкес-Абрамс
1
У Solaris также есть / proc, и техника там работает просто отлично. Не знаю о BSD.
Патрик
2
Я просто должен добавить, что это круто.
n0pe
1
@ Патрик: Вы не можете создать жесткую ссылку, чтобы «восстановить» файл из /proc. Жесткие ссылки работают только в одной и той же файловой системе, а не в файловых системах, и, поскольку /procэто отдельная файловая система без возможности записи, вы не можете создавать жесткие ссылки на нее. Вы можете скопировать файл, /procхотя.
Camh
5

Ядро делает подсчет ссылок на ссылки на индекс. См. Мой ответ на вопрос " Что происходит, когда я закрываю () дескриптор файла?" ,

Удаление открытых файлов, вероятно, не более эффективный механизм DOS, чем просто открытие файлов. ulimitОткрытых файлов обеспечивает некоторую защиту от этой попытки DOS. Это относится ко всем открытым файлам, удаленным или нет.

BillThor
источник
5

Файл удаляется в файловой системе только после того, как исчезли все ссылки на него. И имена, и открытые дескрипторы считаются ссылками. Пока файл открыт в программе, он не удаляется, хотя большинство систем не позволяют вам воссоздать имя для него.

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

Насколько мне известно, вы не можете воссоздать ссылку на файл в стандартной системе Linux (если не считать обход драйвера файловой системы с помощью debugfsаналогичных методов), но вы можете легко восстановить содержимое: cat /proc/12345/fd/42где 12345 - это идентификатор процесса, в котором открыт файл. и 42 - номер дескриптора файла.

В NFS, когда вы удаляете файл, который все еще открыт в каком-либо клиенте, сервер NFS переименовывает файл на сервере, но не удаляет его, пока все клиенты не выпустят файл. По моему опыту, новое имя .nfs…, хотя я не знаю, является ли оно одинаковым во всех реализациях NFS.

Жиль "ТАК - прекрати быть злым"
источник