Лучший способ сделать крюк выключения?

9

Поскольку Ubuntu уже некоторое время использует upstart, я бы хотел использовать задание upstart для корректного завершения работы определенных приложений при завершении работы системы или перезагрузке. Важно, чтобы выключение или перезагрузка системы были приостановлены до тех пор, пока эти приложения не будут закрыты.

Иногда приложения будут запускаться вручную, а при выключении системы должен автоматически завершаться скрипт (который у меня уже есть). Поскольку приложения не могут быть надежно завершены без запуска (почти всех) других служб, завершение приложений должно быть выполнено до начала остального завершения работы.

Я думаю, что смогу решить эту проблему с помощью выскочки, которая будет срабатывать при выключении, но я не уверен, какие события мне следует использовать и каким образом. До сих пор я прочитал следующие (частично противоречащие) утверждения:

  • В upstart нет общего события отключения
  • Используйте строфу, как start on starting shutdownв определении работы
  • Используйте строфу, как start on runlevel [06S]в определении работы
  • Используйте строфу, как start on starting runlevel [06S]в определении работы
  • Используйте строфу, как start on stopping runlevel [!06S]в определении работы

Из этих рекомендаций вытекают следующие вопросы:

  • Есть или нет общее событие выключения в выскочке Ubuntu?
  • Каков рекомендуемый способ реализации «крюка отключения»?
  • Когда запускаются события runlevel [x]; это при входе на уровень выполнения или при входе на уровень выполнения?
  • Можем ли мы использовать что-то вроде start on starting runlevel [x]или start on stopping runlevel [x]?
  • Что будет лучшим решением для моей проблемы?

большое спасибо

Binarus
источник

Ответы:

2

startingи runlevelэто отдельные события, так что вы не можете осмысленно сказать starting runlevel N.

runlevel NСобытие генерируется в начале ввода уровня выполнения. Если вы, start on runlevel Nто ваша задача выполняется при входе. Способ запуска, когда вход на уровень выполнения завершен, есть run on started rc RUNLEVEL=N.

Насколько я понимаю, вам нужно start on runlevel [06S]делать то, что вы хотите; теоретически он должен работать до того, как что-либо еще будет остановлено. Для более точного управления вы можете использовать start on stopping apache or stopping mysql or ...так, чтобы ваша задача выполнялась до того, как какой-либо из них может быть закрыт.


Отредактировано, чтобы изменить уровень выполнения 5 на S.

geekosaur
источник
1
Кроме того, единственная причина, по которой происходит выдающееся startupсобытие, заключается в том, что для «заправки насоса» необходимо что- то . После того, как это одно привилегированное событие отправлено, все остальное может быть определено заданиями и заданиями, инициированными startup. Что касается того, чтобы не было единственного shutdownсобытия, есть слишком много различных видов shutdownдля того, чтобы это было значимым. Лучше зависеть напрямую от рабочих мест, которые вам нужны.
geekosaur
Большое спасибо. Я с благодарностью принимаю ваш ответ, так как он отвечает на мои вопросы и решает проблему. Тем не менее, у меня есть дополнительный вопрос / комментарий (который, однако, не связан с проблемой): AFAIK, цель upstart - полностью заменить концепцию уровня запуска. Тот факт, что нам нужно полагаться на уровни выполнения, чтобы получить глобальный хук отключения, противоречит этой цели. Я думаю, выскочку придется представить такое событие. Я четко понимаю, что было бы лучше зависеть от рабочих мест, которые нам действительно нужны, но, с другой стороны, в моем случае это целая куча рабочих мест ... продолжение ...
Binarus
(почти все, что работает), и я даже не смею думать о том, чтобы выяснить взаимосвязь между процессами, запущенными на блоке (ps -Alf), и заданиями, которые управляют этими процессами; наверняка нет соотношения 1: 1. Существуют задания, которые не связаны ни с какими процессами (например, с настройкой сети), и я полагаю, что существует достаточно процессов, которые в любом случае не связаны с заданиями, особенно при ручном запуске.
Оли
Upstart заменил жестко закодированные уровни запуска; насколько я могу судить, концепция уровня запуска не исчезает, она просто определена в пространстве пользователя. Если вы беспокоитесь о такой длительной перспективе, то вы хотите использовать мое последнее предложение о запуске on stopping servicea or stoping serviceb or ...для любых служб, которые вам нужны.
geekosaur
-1 за несколько неточностей. Ужасно, это не будет работать на самом деле. остановка при запуске rc RUNLEVEL = [016] ничем не отличается от остановки «остановка на уровне выполнения [016]». Это связано с тем, что ни одно из этих событий не заблокирует отключение. Также существует недопустимый синтаксис, так как «запуск включен» недопустим. В целом, это только запутывает проблему, на самом деле это не помогает. Извините, что так поздно! Просто просматривая старые ответы.
SpamapS
2

Чтобы остановить отключение, пока ваша работа останавливается, вы можете использовать это:

stop on starting rc RUNLEVEL=[016]

Это будет работать, потому что первое, что происходит, когда вы вводите «shutdown», это уровень Tunlevel 0. rc запускается на уровне выполнения, и переход из остановленного -> запуска полностью блокируется, пока все задания, которые также должны изменить состояние, не завершат это состояние.

Вы хотите убедиться, что ваш процесс быстро реагирует на SIGTERM. Если он не отвечает в течение 5 секунд, выскочка отправит его SIGKILL. Вы можете поднять это с помощью «kill timeout X».

Цифра 1, кстати, немного хитрая, вам нужно убедиться, что ваш запуск включает что-то, что начинается с уровня запуска [2345] в тот момент, чтобы пользователь, переходящий на однопользовательский режим обслуживания, снова начал свою работу. К счастью, много работы ушло на то, чтобы сделать это предложенным обычным началом

start on runlevel [2345]

Также в некоторых случаях вам нужно что-то, что будет работать до тех пор, пока сеть не выйдет из строя (например, dbus / network-manager). За что ты хочешь

stop on deconfiguring-networking

Это событие, генерируемое позже при завершении работы, которое также будет заблокировано до тех пор, пока все задания, использующие его, не завершат свои переходы в состоянии.

SpamapS
источник
Вы start on starting ... имели в виду, что не имеет смысла останавливать мой крюк отключения на чем-либо. start on starting rc RUNLEVEL=[016]будет иметь гораздо больше смысла. И, может быть, taskдобавили туда, чтобы убедиться, что он может завершиться до того, как начнутся другие дела
Теджей Кардон
0

Geekosaur, большое спасибо за вашу помощь.

В то же время я попробовал start on runlevel [016]метод, но он не работал, и я думаю, что понимаю, почему:

Задание действительно запущено, но процесс выключения не был заблокирован, пока задание не было выполнено. Теперь я совершенно уверен, что эти события startingи stoppingявляются единственными событиями, которые можно использовать в определении задания для блокировки других заданий, и я думаю, что это то, о чем пытаются рассказать руководства Upstart. Следовательно, использование события уровня запуска никогда не приведет к блокировке других заданий или процессу завершения работы; таким образом, это бесполезно для моей цели.

Вместо этого у меня, кажется, есть две возможности:

  1. Следуя одному из ваших предложений, найдите все задания, которые нужны соответствующим приложениям, и включите все из них в событие запуска для сценария следующим образом:

    start on stopping job1 or stopping job2 or ...
    

    Это так много работы, что я серьезно думаю о создании списка заданий и запуске его через sed, чтобы автоматически создать стартовый раздел для моей работы, который включает в себя все задания, которые обычно выполняются в системе.

    Преимущество будет состоять в том, что соответствующие приложения будут закрыты, даже если кто-то остановит одно из предварительных условий вручную (в отличие от остановки их путем изменения / выключения / перезагрузки уровня выполнения).

  2. Найдите одно задание, которое будет остановлено вначале при перезагрузке / выключении системы (назовем это задание «FirstJob»), и используйте это задание в следующем разделе:

    start on stopping FirstJob
    

    Основными недостатками было бы то, что я не знаю, существует ли такая работа вообще, и действительно ли эта работа зависит от всех других заданий, от которых зависит соответствующее приложение («зависит от другой работы» в данном случае означает «будет остановлено»). полностью, прежде чем другая работа начинает останавливаться ").

Я не уверен, какая из двух возможностей лучше ...

Binarus
источник
Я бы сейчас делал sedсценарий, если бы я был на вашем месте.
geekosaur