Як програма журналу може продовжувати вести журнал до видаленого файлу?


12

З Інструментів живлення Unix, 3-е видання : Замість того, щоб видаляти файл, очистіть його в розділі:

Якщо активний процес відкриває файл (не рідкість для файлів журналів), видалення файлу та створення нового не вплине на програму журналу; ці повідомлення просто продовжуватимуть переглядати файл, який більше не пов’язаний . Видалення файлу не порушує асоціації, і він очищає файл, не впливаючи на програму реєстрації.

( наголос мій )

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

Відповіді:


11

Видаляючи файл, ви дійсно видаляєте посилання на файл (до inode). Якщо хтось уже відкрив цей файл, він може зберегти дескриптор файлу, який у них є. Файл залишається на диску, займаючи місце, і його можна записувати та читати, якщо у вас є доступ до нього.

unlinkФункція визначається за допомогою такої поведінки POSIX:

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

Ця порада через таку поведінку. Демон відкриє файл, і він не помітить, що його видалено (якщо тільки він не контролював його конкретно, що є рідкістю). Він буде пильно писати до наявного дескриптора файлів, який він має: ви будете займати (більше) місця на диску, але ви не зможете побачити жодне з повідомлень, які він пише, тож ви справді в гіршому обох світів. Якщо замість цього файлу обрізати нуль, тоді простір буде звільнено негайно, а будь-які нові повідомлення будуть додані в новому кінці файлу, де ви зможете їх побачити.

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

Якщо кількість посилань на файл дорівнює 0, коли всі дескриптори файлів, пов'язані з файлом, закриті, простір, який займає файл, буде звільнений і файл більше не буде доступним.

Таким чином, ви не втрачаєте місця на диску назавжди, але нічого не отримуєте, видаляючи файл, і втрачаєте доступ до нових повідомлень.


1
Що станеться, якщо користувач (скажімо, root тут) спробує від’єднатись /proc/x/fd/y? Чи це може призвести до того, що процес не зможе записати у дескриптор файлу, чи це незаконна операція?
nanofarad

@hexafraction - /proc/*/fd/*це посилання на реальні файли, тому їх видалення не видалить файл. Я б запропонував вам поекспериментувати :) (не над виробничою системою, звичайно!)
Руслан

1
@MichaelHomer Можливо, ви могли б уточнити у своїй відповіді, що після того, як файл від’єднано, процес, де дескриптор файлу вказує на нього, може зв'язати його ще раз, тим самим шляхом чи ні. Іноді це може бути корисно.
lgeorget

@hexafraction Ну, це лише представлення (у просторі файлової системи) стану процесу та об'єктів. Якщо ви видалите ці представлення з простору файлової системи, з фактичним процесом нічого не повинно відбуватися, якщо тільки він (або якийсь інший процес) не покладається на те, що там є представлення. Не впевнені, що ви можете використовувати безперервно rmвсередину /procабо /sysбез того, щоб система відмовлялася від них.
Девід Тонхофер

@lgeorget Як це досягнуто?
Майкл

8

Саме так.

Файли тричленні.

  • Вміст, тобто плоский масив байтів, записаний десь на диску або сформований під час руху.
  • Індекс вузол , або індексний дескриптор для стислості, яка є структурою даних заповнюються і використовуються ядром. Він містить усі метадані (розмір, дозвіл тощо) про файл, а також вказівки на розташування вмісту файлу.
  • Один або кілька записів каталогу , які локації, маніпулюють , як доріжки , як /home/user/personal_file, які діють як ручки , через які ви можете використовувати файл, змінювати його вміст, змінювати його метадані і т.д.

Відкриваючи файл, ви даєте шлях до операційної системи, і він повертає вам обробку безпосередньо до inode. Завдяки цій ручці, що називається дескриптором файлу, ви можете маніпулювати файлом так, як вам хочеться (або принаймні, як це дозволяє ОС).

Ви ніколи не можете видалити безпосередньо індею, вам потрібно дати шлях до ОС, щоб вимагати видалення. Отже, коли ви хочете видалити файл, ви видалите лише запис каталогу. Якщо файл має інші записи каталогів, він буде продовжувати бути доступним, і навіть якщо його немає, його inode не буде видалений, поки ще є дескриптори файлів, які вказують на нього. @ Відповідь Майкла Хомера є більш технічною та детальнішою на цю конкретну тему.


4

Інші 2 відповіді добре пояснюють проблему - файл не «видаляється», доки всі посилання каталогів на нього та всі відкриті дескриптори файлів до нього не зникнуть.

Щоб уникнути цього, корисно використовувати

> /var/log/bigfile

замість

rm -f /var/log/bigfile

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

Якщо ви видалили файл і перебуваєте в Linux, де у вас є файлова система / proc / fd, ви все одно можете користуватися

> /proc/12345/fd/3

нульовий вміст файлу (припустимо, 12345 - ваш ідентифікатор процесу, а 3 - номер fd великого файлу). Це може бути збереженням життя, якщо ваш диск працює повноцінно, і ви не можете вбити процес, який записує ваш файл журналу, з якоїсь причини.


> /var/log/bigfileвидаляє наявні дані у файлі, але не зупиняє програми писати там. Є дуже мало обставин, коли це правильно. Я б сказав, що це погана звичка потрапляти. Якщо ви хочете видалити файл, використовуйте rm. Якщо ви хочете зупинити програми, які там пишуть, вбийте їх або іншим чином змусьте їх припинити писати до чи після видалення.
Жил 'ТАК - перестань бути злим'

1
@Giles, ця тема стосується того, що видалення не допоможе, якщо програма все ще відкриває файл. І якщо ваш диск переповнений, тому що якась програма погано поводиться і syslogdзаповнює /var/log/messages, > /var/log/messagesце набагато кращий варіант, ніж вбивство syslogd. Звичайно, це не повинно перешкодити вам аналізувати, в чому полягає проблема.
Guntram Blohm підтримує Моніку
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.