Czy pliki .pid są wiarygodne w celu ustalenia, czy proces jest uruchomiony?

11

Wiele programów, takich jak sshd, tworzy pliki .pid w / var / run /, które zawierają ich identyfikatory procesów. Czy te pliki są wiarygodne w celu ustalenia, czy proces jest uruchomiony? Domyślam się, że pliki te są tworzone ręcznie przez proces i dlatego pozostaną w systemie plików, jeśli program się zawiesi.

osob
źródło

Odpowiedzi:

16

w prostych słowach : nie : proces (np. demon) może ulec awarii i nie mieć czasu na wyczyszczenie pliku .pid.

Technika zapewniająca większą pewność stanu programu: użyj jawnego kanału komunikacyjnego, takiego jak gniazdo. Zapisz port gniazda w pliku i pozwól, aby supervisorproces go sprawdził.

Możesz także skorzystać z usług DBus w systemie Linux: zarejestruj konkretną nazwę i poproś proces swojego przełożonego (jakkolwiek ją nazwiesz) o sprawdzenie tej nazwy.

Istnieje wiele technik.

Należy pamiętać o jednej rzeczy: zarządzanie plikami PID nie jest obowiązkiem systemu operacyjnego.

Jldupont
źródło
1
Istnienie pliku pid, POŁĄCZONEGO z istnieniem procesu, powinno jednak wystarczyć. Jeśli proces zakończy się, możesz to sprawdzić. PID są ponownie wykorzystywane, ale niezbyt często.
MarkR
2
to, jak często pid jest ponownie wykorzystywany, zależy od konkretnego systemu. Widziałem system, w którym PID były zmieniane co najmniej raz dziennie. Musisz sprawdzić pid, czy istnieje proces i wydaje się, że proces ten jest tym, w którym spodziewasz się, że będziesz właścicielem pid.
@atk: dokładnie. Nie ma standardu per se, a nawet jeśli taki był, może nie być przestrzegany przez niektóre implementacje. Np. Mogę stworzyć demona, który w ogóle nie zapisuje pliku PID i użyć tylnego kanału, aby uzyskać polecenia zarządzania.
jldupont
@atk: niestety nie ma sposobu, aby zapewnić, że PID nie zostanie ponownie użyty między czasem sprawdzania a czasem użycia ...
SamB
3

Jldupont ma rację, stwierdzając, że pliki .pid niewiarygodne w określaniu, czy proces jest uruchomiony, ponieważ plik może nie zostać usunięty w przypadku awarii.

Pomijając warunki wyścigu, często używam pgrep, gdy muszę wiedzieć, czy proces jest uruchomiony. Mógłbym wtedy odnieść dane wyjściowe do plików .pid, jeśli uzna to za konieczne.

jschmier
źródło
3

Plik zawierający identyfikator procesu nie jest wiarygodny, sprawdź, czy proces jest uruchomiony, czy nie. Jest to tylko wiarygodne źródło, aby dowiedzieć się, jaki jest ostatni podany identyfikator procesu.

Gdy masz identyfikator procesu, musisz wykonać późniejsze sprawdzenie, czy proces naprawdę działa.

Oto przykład:

#!/usr/bin/env sh

file="/var/run/sshd.pid"
processid=$(cat /var/run/sshd.pid)

if [ ! -f ${file} ]; then
    echo "File does not exists: ${file}"
    exit 1
fi

if [ ! -r ${file} ]; then
    echo "Insufficient file persmissons: ${file}"
    exit 1
fi

psoutput=$(ps -p ${processid} -o comm=)

if [ $? == 0 ];then
    if [ ${psoutput} == "sshd" ]; then
        echo "sshd process is realy running with process id ${processid}"
        exit 0
    else
        echo "given process id ${processid} is not sshd: ${psoutput}"
        exit 1
    fi
else
    echo "there is no process runing with process id ${processid}"
    exit 0
fi

pgrep to fajne polecenie, ale będziesz mieć kłopoty, gdy uruchomisz wiele instancji. Na przykład, jeśli masz zwykły sshd działający na porcie TCP / 22 i masz inny sshd działający na porcie TCP / 2222, wtedy pgrep dostarczy dwa identyfikatory procesu podczas wyszukiwania sshd ... kiedy normalny sshd ma swój pid w / var /run/sshd.pid, a drugi może mieć swój pid w /var/run/sshd-other.pid, możesz wyraźnie odróżnić procesy.

I nie zaleca się używanie tylko ps , rurociągi za pośrednictwem jednej lub kilku rur z grep i grep -v próbuje odfiltrować wszystkie inne rzeczy, które nie interesuje ... to trochę jak za pomocą

find . | grep myfile

dowiedzieć się, czy plik się kończy.

Mirko Steiner
źródło
2

Sprawdzanie istnienia procesu z tym samym pid, co plik, nie jest niezawodne.

Ale wiele implementacji pliku pidfile blokuje również plik pid, więc jeśli proces umrze, blokada zniknie. Pod warunkiem, że mechanizm blokujący jest niezawodny, sprawdzanie, czy plik jest nadal zablokowany, jest stosunkowo niezawodnym mechanizmem do określania, czy oryginalny proces nadal działa.

Paul Brannan
źródło
1

Jldupont ma rację.

Możesz jednak wysłać procesowi sygnał 0 (kill -s 0 pid), aby sprawdzić, czy proces nadal trwa (zakładając, że masz uprawnienia do wysyłania takiego sygnału - ogólnie tylko właściciel procesu może wysłać to sygnał).


źródło
4
Ale sprawdzanie istnienia procesu z tym PID nie oznacza, że ​​interesuje Cię PID.
janm
0

Zgadzam się z jschmier.

W niektórych systemach nie masz dostępu do pgrep. W takim przypadku możesz ps -aef | grep <pid>sprawdzić, czy proces naprawdę działa.

użytkownik29584
źródło
1
Kluczowym punktem pytania było „wiarygodne”. Robienie ps i szukanie PID nie jest wiarygodne.
janm
cóż ... zakładając, że znasz tę nazwę programu, dlaczego uważasz ps-aef | grep jest zawodny?
user29584,
3
Warunki wyścigu: stan systemu zmienił się do czasu zakończenia ps. Tytuły procesów: inny proces może mieć tytuł podobny do tego, który Cię interesuje. Wiele instancji: Rozważ system z dwiema instancjami tej samej usługi, każda z plikiem PID. Jedna zawiesza się, a druga uruchamia się ponownie i otrzymuje identyfikator PID pierwszej usługi. Jak ty to mówisz? Itd. Niezawodny, niemożliwy do poprawienia z powodu warunków wyścigowych, i istnieją niezawodne techniki, które po prostu działają. Dla niezawodnej alternatywy patrz na przykład cr.yp.to/daemontools.html
janm