Надежны ли файлы .pid для определения, запущен ли процесс?

11

Многие программы, такие как sshd, создают файлы .pid в / var / run /, которые содержат свои идентификаторы процессов. Надежны ли эти файлы для определения, запущен ли процесс? Я предполагаю, что эти файлы создаются вручную процессом и, следовательно, все равно останутся в файловой системе в случае сбоя программы.

Indiv
источник

Ответы:

16

Проще говоря, нет : процесс (например, демон) может завершиться сбоем и не успеть очистить свой файл .pid.

Техника для большей уверенности в состоянии программы: использовать явный канал связи, такой как сокет. Запишите порт сокета в файл и supervisorпросмотрите его.

Вы также можете использовать службы DBus в Linux: зарегистрировать определенное имя и попросить ваш процесс супервизора (как вы его называете) проверить это имя.

Есть множество методов.

Помните одно: ОС не несет ответственности за управление файлами PID.

jldupont
источник
1
Однако наличие файла pid, совмещенного с существованием процесса, должно быть достаточным. Если процесс завершится, вы можете это проверить. PID действительно используются повторно, но не очень часто.
MarkR
2
то, как часто pid используется повторно, зависит от конкретной системы. Я видел систему, в которой PID запускались по крайней мере ежедневно. Вы должны проверить pid, что есть процесс, и что процесс, как вы ожидаете, будет владельцем pid.
@atk: точно. Стандарт не существует как таковой, и даже если бы он был, он может быть не соблюден некоторыми реализациями. Например, я могу создать демона, который вообще не пишет PID-файл, и использовать обратный канал для получения команд управления.
Jldupont
@atk: к сожалению, нет способа гарантировать, что PID не будет повторно использоваться между временем проверки и временем использования ...
SamB
3

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

Помимо условий гонки, я часто использую pgrep, когда мне нужно знать, запущен ли процесс. Затем я мог бы сопоставить выходные данные с файлами .pid, если я счел это необходимым.

jschmier
источник
3

Файл, содержащий идентификатор процесса, не является надежным. Определите, запущен процесс или нет. Это просто надежный источник для определения последнего заданного идентификатора процесса.

Когда у вас есть идентификатор процесса, вы должны дополнительно проверить, действительно ли процесс запущен.

Вот пример:

#!/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 - хорошая команда, но у вас будут проблемы, если у вас запущено несколько экземпляров. Например, если у вас есть обычный sshd, работающий на порту TCP / 22, и у вас есть другой sshd, работающий на порту TCP / 2222, тогда pgrep доставит два идентификатора процесса при поиске sshd ... когда обычный sshd имеет свой pid в / var /run/sshd.pid, а другой может иметь свой pid в /var/run/sshd-other.pid, чтобы вы могли четко разграничить процессы.

Я не рекомендую использовать только ps , пропуская через один или несколько каналов с помощью grep и grep -v, пытаясь отфильтровать все другие вещи, которые вас не интересуют ... это немного похоже на использование

find . | grep myfile

выяснить, если файл выходит.

Мирко Штайнер
источник
2

Ненадежно просто проверять существование процесса с тем же pid, который содержится в файле.

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

Пол Браннан
источник
1

Jldupont правильно.

Тем не менее, вы можете отправить процессу сигнал 0 (kill -s 0 pid), чтобы увидеть, если процесс еще жив (при условии, что у вас есть права на отправку такого сигнала - в общем, отправлять может только владелец процесса). это сигнал).


источник
4
Но проверка существования процесса с этим PID не означает, что PID вас заинтересует.
Янв
0

Я согласен с jschmier.

В некоторых системах вы не получаете доступ к pgrep. В таком случае вы можете ps -aef | grep <pid>узнать, действительно ли процесс запущен.

user29584
источник
1
Ключевой момент в вопросе был «надежный». Делать ps и искать PID ненадежно.
Янв
хорошо ... при условии, что вы знаете это имя программы, почему вы думаете, что ps -aef | grep ненадежен?
user29584
3
Условия гонки: состояние системы изменилось к моменту завершения ps. Заголовки процессов: другой процесс может иметь заголовок, аналогичный интересующему вас. Несколько экземпляров. Рассмотрим систему с двумя экземплярами одного и того же сервиса, каждый с файлом PID. Один отказывает, а другой перезапускается и получает PID первой службы. Как вы говорите? И т.д. Не надежно, невозможно получить права из-за условий гонки, и есть надежные методы, которые просто работают. Для надежной альтернативы см., Например, cr.yp.to/daemontools.html
январь