W jaki sposób program rejestrujący może nadal logować się do usuniętego pliku?

12

Z Unix Power Tools, wydanie trzecie : Zamiast usuwania pliku, opróżnij sekcję:

Jeśli w aktywnym procesie plik jest otwarty (nierzadko w przypadku plików dziennika), usunięcie pliku i utworzenie nowego nie wpłynie na program rejestrujący; te wiadomości będą po prostu przechodzić do pliku, który nie jest już połączony . Opróżnienie pliku nie powoduje przerwania powiązania, a zatem usuwa plik bez wpływu na program rejestrujący.

( moje podkreślenie )

Nie rozumiem, dlaczego program będzie nadal logował się do usuniętego pliku. Czy to dlatego, że pozycja deskryptora pliku nie jest usuwana z tabeli procesów?

Maniak
źródło

Odpowiedzi:

11

Kiedy usuwasz plik, tak naprawdę usuwasz link do pliku (do i-węzła). Jeśli ktoś już ma ten plik otwarty, może zachować deskryptor pliku, który ma. Plik pozostaje na dysku, zajmuje miejsce i można go zapisać i odczytać, jeśli masz do niego dostęp.

unlinkFunkcja jest zdefiniowana z tego zachowania przez POSIX:

Gdy liczba linków do pliku osiągnie wartość 0 i żaden proces nie otworzy pliku, przestrzeń zajmowana przez plik zostanie zwolniona, a plik nie będzie już dostępny. Jeśli jeden lub więcej procesów ma otwarty plik po usunięciu ostatniego linku, link zostanie usunięty przed powrotem unlink (), ale usunięcie zawartości pliku zostanie odroczone do momentu zamknięcia wszystkich odniesień do pliku .

Ta rada z powodu tego zachowania. Demon otworzy plik i nie zauważy, że został usunięty (chyba że monitorował go konkretnie, co jest rzadkie). Będzie beztrosko zapisywać do istniejącego deskryptora pliku, który ma: będziesz nadal zajmować (więcej) miejsca na dysku, ale nie będziesz w stanie zobaczyć żadnej wiadomości, którą pisze, więc naprawdę jesteś w najgorszym obu światów. Jeśli zamiast tego skrócisz plik do zera, miejsce zostanie natychmiast zwolnione, a wszelkie nowe wiadomości zostaną dołączone na nowym końcu pliku, gdzie możesz je zobaczyć.

Ostatecznie, gdy demon zakończy działanie lub closes plik , przestrzeń zostanie zwolniona. Nikt nowy nie może otworzyć pliku w międzyczasie (inaczej niż poprzez specyficzne dla systemu interfejsy odblaskowe, takie jak Linux/proc/x/fd/... ). Gwarantuje to również, że:

Jeśli liczba odsyłaczy pliku wynosi 0, gdy wszystkie deskryptory pliku skojarzone z plikiem zostaną zamknięte, przestrzeń zajmowana przez plik zostanie zwolniona, a plik nie będzie już dostępny.

Dzięki temu nie tracisz na stałe miejsca na dysku, ale nic nie zyskujesz poprzez usunięcie pliku i tracisz dostęp do nowych wiadomości.

Michael Homer
źródło
1
Co się stanie, jeśli użytkownik (powiedzmy tutaj root) spróbuje się rozłączyć /proc/x/fd/y? Czy spowodowałoby to, że proces nie zapisuje się do deskryptora pliku, czy jest to nielegalna operacja?
nanofarad
@ hexafraction /proc/*/fd/*to dowiązania symboliczne do prawdziwych plików, więc usunięcie ich nie spowoduje usunięcia pliku. Proponuję eksperymentować :) (oczywiście nie w systemie produkcyjnym!)
Ruslan
1
@MichaelHomer Być może możesz wyjaśnić w swojej odpowiedzi, że gdy plik zostanie odłączony, proces mający deskryptor pliku wskazujący go może połączyć go ponownie, pod tą samą ścieżką, czy nie. Czasami może to być przydatne.
lgeorget
@ hexafraction Cóż, to tylko reprezentacje (w przestrzeni systemu plików) stanu procesu i obiektów. Jeśli usuniesz te reprezentacje w przestrzeni systemu plików, w rzeczywistym procesie nic nie powinno się stać - chyba że (lub jakiś inny proces) polega na tym, że reprezentacja istnieje. Nie jestem pewien, czy możesz używać rmnietrzymanie moczu w środku /proclub /sysbez uprzedzenia przez system.
David Tonhofer,
@lgeorget Jak to osiągnąć?
Michael
8

Dokładnie.

Pliki są trójdzielne.

  • Treść, czyli płaski zestaw bajtów zapisanych gdzieś na dysku lub generowanych w locie.
  • Węzeł indeksu lub iwęzeł za krótki, co jest strukturą danych wypełniane i wykorzystywane przez jądro. Zawiera wszystkie metadane (rozmiar, uprawnienia itp.) Dotyczące pliku, a także wskazuje na lokalizację zawartości pliku.
  • Jeden lub więcej wpisów katalogowych , które są lokalizacje, jak manipulować ścieżkami jak /home/user/personal_file, które działają jak uchwyty, przez które można wykorzystać plik, modyfikować jego zawartość, zmienić jego metadanych, itd

Po otwarciu pliku podajesz ścieżkę do systemu operacyjnego, a on zwraca uchwyt bezpośrednio do i-węzła. Za pomocą tego uchwytu, zwanego deskryptorem pliku, można manipulować plikiem w dowolny sposób (lub przynajmniej w zakresie dozwolonym przez system operacyjny).

Nigdy nie możesz bezpośrednio usunąć i-węzła, musisz podać ścieżkę do systemu operacyjnego, aby wymagać usunięcia. Tak więc, jeśli chcesz usunąć plik, usuwasz tylko pozycję katalogu. Jeśli plik ma inne wpisy katalogu, będzie nadal dostępny, a nawet jeśli nie, jego i-węzeł nie zostanie usunięty, dopóki nadal wskazują na niego deskryptory plików. Odpowiedź @ MichaelHomer jest bardziej techniczna i bardziej szczegółowa na ten temat.

lgeorget
źródło
4

Pozostałe 2 odpowiedzi wyjaśnić kwestię dobrze - plik nie dostać „skasowany”, dopóki wszystkie linki katalog do niej i wszystkie otwarte deskryptory plik, aby go nie ma.

Aby tego uniknąć, warto używać tego nawyku

> /var/log/bigfile

zamiast

rm -f /var/log/bigfile

ponieważ to po prostu resetuje zawartość do 0 bajtów zamiast ją usuwać, i nadal możesz zobaczyć, co jest do niej napisane.

Jeśli usunąłeś plik i korzystasz z systemu Linux, na którym znajduje się system plików / proc / fd, nadal możesz go używać

> /proc/12345/fd/3

aby wyzerować zawartość pliku (zakładając, że 12345 jest twoim identyfikatorem procesu, a 3 to numer fd dużego pliku). Może to uratować życie, jeśli dysk jest pełny i z jakiegoś powodu nie możesz zabić procesu zapisywania pliku dziennika.

Guntram Blohm wspiera Monikę
źródło
> /var/log/bigfileusuwa istniejące dane z pliku, ale nie powstrzymuje programów przed zapisem. Jest bardzo niewiele okoliczności, w których jest to właściwe. Powiedziałbym, że to zły nawyk. Jeśli chcesz usunąć plik, użyj rm. Jeśli chcesz zatrzymać programy, które tam piszą, zabij je lub w inny sposób spraw, aby przestały pisać, przed usunięciem lub po nim.
Gilles „SO- przestań być zły”
1
@ Giles, ten temat dotyczy faktu, że usunięcie nie pomoże, jeśli program nadal ma otwarty plik. A jeśli twój dysk jest pełny, ponieważ niektóre programy źle się zachowują i syslogdzapełniają się /var/log/messages, > /var/log/messagesjest znacznie lepszą opcją niż zabijanie syslogd. Oczywiście nie powinno to powstrzymywać Cię przed analizowaniem, na czym polega problem.
Guntram Blohm wspiera Monikę