Как программа-журнал может продолжать входить в удаленный файл?

12

Из Unix Power Tools, 3-е издание : вместо удаления файла очистите раздел:

Если у активного процесса есть открытый файл (не редкость для файлов журнала), удаление файла и создание нового не повлияет на программу ведения журнала; эти сообщения будут продолжать идти в файл, который больше не связан . Очистка файла не нарушает ассоциацию, поэтому он очищает файл, не затрагивая программу регистрации.

( акцент мой )

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

Компьютерщик
источник

Ответы:

11

Когда вы удаляете файл, вы действительно удаляете ссылку на файл (на индекс). Если кто-то уже открыл этот файл, он может сохранить дескриптор файла, который у него есть. Файл остается на диске, занимая место, и может быть записан и прочитан, если у вас есть к нему доступ.

unlinkФункция определяется с помощью такого поведения POSIX:

Когда счетчик ссылок на файл становится равным 0, и ни один процесс не имеет открытого файла, пространство, занимаемое файлом, должно быть освобождено, и файл больше не будет доступен. Если один или несколько процессов открывают файл при удалении последней ссылки, ссылка должна быть удалена до возврата unlink (), но удаление содержимого файла должно быть отложено до тех пор, пока все ссылки на файл не будут закрыты .

Этот совет из-за такого поведения. У демона будет открытый файл, и он не заметит, что он был удален (если он не контролировал его специально, что редко). Он будет беспечно записывать в существующий дескриптор файла: он будет занимать (больше) места на диске, но вы не сможете увидеть ни одно из сообщений, которые он пишет, так что вы действительно в худшем обоих миров. Если вместо этого вы усекаете файл до нулевой длины, пространство сразу освобождается, и любые новые сообщения будут добавляться в новом конце файла, где вы сможете их увидеть.

В конце концов, когда демон завершает работу или closeсоздает файл , пространство освобождается. Никто новый не может открыть файл за это время (кроме как через отражающие интерфейс системы, такие как Linux/proc/x/fd/... ). Также гарантируется, что:

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

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

Майкл Гомер
источник
1
Что произойдет, если пользователь (скажем, root) попытается разорвать связь /proc/x/fd/y? Это приведет к тому, что процесс не сможет записать в дескриптор файла, или это недопустимая операция?
нанофарад
@hexafraction /proc/*/fd/*- это символические ссылки на реальные файлы, поэтому удаление их не приведет к удалению файла. Я бы предложил вам поэкспериментировать :) (конечно, не на производственной системе!)
Руслан
1
@MichaelHomer Возможно, вы могли бы уточнить в своем ответе, что, если файл не связан, процесс, имеющий файловый дескриптор, указывающий на него, может снова связать его, по тому же пути или нет. Иногда это может быть полезно.
lgeorget
@hexafraction Ну, это просто представления (в пространстве файловой системы) состояния процесса и объектов. Если вы удалите эти представления в пространстве файловой системы, с самим процессом ничего не должно произойти - если только он (или какой-то другой процесс) не полагается на это представление. Не уверен, что вы можете использовать rmнедержание внутри /procили /sysбез предупреждения системы в любом случае.
Дэвид Тонхофер
@lgeorget Как это сделать?
Майкл
8

В точку.

Файлы являются трехсторонними.

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

Когда вы открываете файл, вы указываете путь к операционной системе, и он возвращает вам дескриптор непосредственно к inode. С помощью этого дескриптора, называемого дескриптором файла, вы можете манипулировать файлом по своему усмотрению (или, по крайней мере, как разрешено ОС).

Вы никогда не можете удалить inode напрямую, вы должны указать путь к ОС, который требует удаления. Таким образом, когда вы хотите удалить файл, вы удаляете только запись каталога. Если у файла есть другие записи каталога, он будет по-прежнему доступен, и даже если у него его нет, его индекс не будет удален, пока на него все еще есть файловые дескрипторы. Ответ @ MichaelHomer является более техническим и более подробным по этой конкретной теме.

lgeorget
источник
4

Два других ответа хорошо объясняют проблему - файл не «удаляется» до тех пор, пока не исчезнут все ссылки на каталог и все дескрипторы открытых файлов.

Чтобы избежать этого, это хорошая привычка использовать

> /var/log/bigfile

вместо того

rm -f /var/log/bigfile

так как это просто сбрасывает содержимое до 0 байтов вместо того, чтобы удалять его, и вы все равно можете видеть, что записано в него.

Если вы удалили файл и находитесь в Linux, где у вас есть файловая система / proc / fd, вы все равно можете использовать

> /proc/12345/fd/3

обнулить содержимое файла (если 12345 - это идентификатор вашего процесса, а 3 - номер большого файла). Это может быть спасением жизни, если ваш диск заполнен и по какой-то причине вы не можете завершить процесс записи файла журнала.

Гунтрам Блом поддерживает Монику
источник
> /var/log/bigfileудаляет существующие данные в файле, но не мешает программам записывать туда. Есть очень мало обстоятельств, когда это правильно. Я бы сказал, что это плохая привычка. Если вы хотите удалить файл, используйте rm. Если вы хотите остановить программы, которые там пишут, убейте их или иным образом заставьте их прекратить писать до или после удаления.
Жиль "ТАК - перестань быть злым"
1
@Giles, эта тема о том, что удаление не поможет, если программа все еще имеет открытый файл. И если ваш диск заполнен, потому что некоторые программы плохо себя ведут и syslogdзаполняют /var/log/messages, > /var/log/messagesэто гораздо лучший вариант, чем убийство syslogd. Конечно, это не должно помешать вам проанализировать, в чем заключается проблема.
Гунтрам Блом поддерживает Монику