От: | Pavel Dvorkin | ||
Дата: | 10.01.24 12:50 | ||
Оценка: | +1 |
Остановка службы
Когда Winlogon вызывает Windows-функцию ExitWindowsEx, эта функция от-
правляет сообщение Csrss — процессу подсистемы Windows — для вызова
Csrss-процедуры завершения работы. Csrss осуществляет циклический перебор
активных процессов и уведомляет их, что система завершает работу. Для каж-
дого системного процесса, за исключением SCM, Csrss ждет несколько секунд,
количество которых определено параметром HKU\.DEFAULT\Control Panel\
Desktop\WaitToKillAppTimeout (по умолчанию 20 с), пока не будет осуществлен
выход из процесса, после чего переходит к следующему процессу. Когда Csrss
встречает процесс SCM, он также уведомляет его о завершении работы системы,
но использует лимит времени, определенный для SCM. Csrss распознает SCM,
используя идентификатор процесса, который Csrss сохранил при регистрации
SCM с Csrss с помощью функции RegisterServicesProcess в ходе инициализа-
ции системы. Лимит времени для SCM отличается от лимита других процессов,
поскольку Csrss знает, что SCM обменивается данными со службами, которым
при остановке нужно осуществить подчистку после своей работы. Поэтому ад-
министратору может понадобиться настроить только лимит времени, выделяе-
мый SCM. Параметр лимита времени SCM находится в разделе реестра HKLM\
SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout и по умолчанию
составляет 12 секунд.
Обработчик остановки SCM отвечает за рассылку уведомлений всем службам,
запросившим уведомление об остановке при своей инициализации с помощью
SCM. SCM-функция ScShutdownAllServices осуществляет циклический перебор
записей служб в базе данных SCM в поиске служб, желающих получить уведомле-
ние об остановке, и отправляет каждой из них команду на остановку. Для каждой
службы, которой отправляется команда на остановку, SCM записывает параметр,
указывающий время ожидания службы, значение которого служба также определяет
при своей регистрации с помощью SCM. SCM отслеживает самое продолжительное
указанное время ожидания. После отправки сообщений об остановке SCM ждет,
либо пока одна из служб, которая была оповещена об остановке, не осуществит
выход, либо пока не пройдет самое продолжительное указанное время.
Если указанное время истечет, а служба не осуществит выход, SCM определя-
ет, не отправила ли одна или несколько служб, от которых ожидался выход, со-
общение SCM о том, что эта служба находится в процессе своей остановки. Если
хотя бы одна служба продвинулась в этом процессе, SCM снова ждет истечения
установленного времени ожидания. SCM продолжает выполнение этого цикла
ожидания, пока либо все службы не осуществят выход, либо ни одна из служб,
в отношении которых осуществляется ожидание, не уведомит его о нахождении
в процессе свой остановки за тот период времени, который указан для ожидания.
Пока SCM занимается отправкой приказов службам на остановку и ожида-
нием их выхода, Csrss ждет выхода от SCM. Если ожидание, осуществляемое
Csrss, заканчивается до того, как будет осуществлен выход SCM (по истечении
времени, указанного в параметре WaitToKillServiceTimeout), Csrss принудительно
завершает работу SCM и продолжает процесс завершения работы системы. Таким
образом, службы, давшие сбой при остановке за отведенное для этого время,
останавливаются принудительно. Такая логика позволяет системе завершать
работу вопреки тем службам, которые никогда не остановятся в результате де-
фектов своей конструкции, но это также означает, что службы, требующие более
20 секунд, не завершат своих действий по остановке.
Кроме того, поскольку порядок остановки ничем не обусловлен, службы,
которые могут зависеть от других служб, для своей первоочередной остановки
не имеют способа сообщить об этом SCM, могут не иметь никаких шансов на
подчистку после своей работы.
В связи с этими потребностями в Windows реализуются предостановочные
уведомления и порядок остановки для противодействия проблемам, вызывае-
мым этими двумя сценариями. Предостановочные уведомления рассылаются
с использованием того же механизма, который используется для уведомлений
об остановке. Уведомления рассылаются тем службам, которые запросили предостановочные
уведомления посредством API-функции SetServiceStatus, и SCM
будет ждать от них подтверждения.
Идея, заложенная в этих уведомлениях, заключается в пометке тех служб,
у которых на подчистку может уйти много времени (это, к примеру, может
касаться служб сервера базы данных), и в выделении им большего количества
времени на завершение их работы. SCM отправит запрос на выяснение хода про-
цесса и будет 3 минуты ждать завершения работы тех служб, которые на него
ответили. Если служба за это время не ответит, она будет принудительно оста-
новлена в рамках процедуры завершения работы системы; в противном случае
она может продолжать свое выполнение столько времени, сколько потребуется,
пока она будет продолжать отвечать на запросы SCM.
Службы, участвующие в предварительной остановке (preshutdown), могут
также определить порядок остановки по отношению к другим службам, также
участвующим в предварительной остановке. Службы, зависящие от первооче-
редной остановки других служб (например, Group Policy должна дождаться
завершения работы службы обновления Windows Update), могут указать свои
зависимости от остановок других служб в параметре реестра HKLM\SYSTEM\
CurrentControlSet\Control\PreshutdownOrder.