制作关机钩的最佳方法?


9

由于Ubuntu现在依赖upstart一段时间,因此我想使用upstart作业在系统关闭或重新引导时正常关闭某些应用程序。在这些应用程序关闭之前,必须停止系统的关闭或重新启动。

有时会手动启动应用程序,并且在系统关闭时应自动以脚本(我已经拥有)结束。由于没有(几乎所有)其他服务都无法可靠地结束应用程序,因此必须在其余的关闭开始之前结束应用程序。

我想我可以通过在关闭时触发的启动工作来解决此问题,但是我不确定应该以哪种方式使用哪些事件。到目前为止,我已经阅读了以下(部分矛盾的)陈述:

  • 新贵中没有一般的关机事件
  • 使用像start on starting shutdown工作定义中的节
  • 使用像start on runlevel [06S]工作定义中的节
  • 使用像start on starting runlevel [06S]工作定义中的节
  • 使用像start on stopping runlevel [!06S]工作定义中的节

从这些建议中,出现以下问题:

  • Ubuntu的暴发户中是否存在一般的关机事件?
  • 建议使用什么方法来实现“关机挂钩”?
  • 运行级别[x]何时触发?输入运行级别时或进入运行级别时,这是什么?
  • 我们可以使用类似start on starting runlevel [x]或的东西start on stopping runlevel [x]吗?
  • 什么是对我的问题最好的解决方案?

非常感谢你

Answers:


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。


1
此外,唯一原因是一位杰出的startup事件是,什么是需要的“黄金泵”。发送一个特权事件后,其他一切都可以并且由触发的作业和任务定义startup。至于没有单个shutdown事件,那么有太多不同种类的事件shutdown才有意义。最好直接依赖于您需要运行的作业。
geekosaur 2011年

非常感谢你。非常感谢您的回答,因为它可以回答我的问题并解决问题。不过,我还有一个问题/评论(尽管与问题无关):AFAIK,完全替换运行级别概念是新贵的目标。我们需要依靠运行级别来获取全局关闭钩子这一事实与这一目标相矛盾。我认为新贵将不得不引入这样的事件。我清楚地了解到,最好依靠我们真正需要的工作,但另一方面,就我而言,这是一大堆工作……续...
Binarus 2011年

(几乎所有正在运行的东西),我什至不敢考虑找出运行在盒子上的进程(ps -Alf)与控制这些进程的作业之间的关系;确保没有1:1关系。有些作业与任何进程都不相关(例如,配置网络),我想有足够的进程无论如何都与作业无关,尤其是在手动启动时。
奥利(Oli)

新贵取代了硬编码的运行级别;据我所确定,运行级别的概念并没有消失,它只是在用户空间中定义。如果您担心这么长的时间,那么您想使用我对运行on stopping servicea or stoping serviceb or ...任何服务所需的最后建议。
geekosaur 2011年

-1为几个错误。放平一点,这实际上是行不通的。在启动的rc上停止RUNLEVEL = [016]没什么不同。frun'在运行级别[016]停止”。这是因为这两个事件都不会阻止关机继续进行。语法也无效,因为“运行于”无效。总而言之,这只会使问题感到困惑,实际上并没有帮助。对不起,这太晚了!只是查看旧答案。
SpamapS 2012年

2

为了在您的作业停止时阻止关机继续进行,您将需要使用以下命令:

stop on starting rc RUNLEVEL=[016]

这将起作用,因为键入“ shutdown”时发生的第一件事是发出tunlevel 0。rc在运行级别启动,从停止->启动的转换将完全阻塞,直到必须更改状态的所有作业都完成了该状态。

您将要确保您的过程快速响应SIGTERM。如果它在5秒钟内没有响应,则新贵将其发送为SIGKILL。您可以使用“ kill timeout X”来提高它。

那里的1,btw有点棘手,您需要确保开始时包含在运行级别[2345]上开始的内容,以便陷入单用户模式维护的用户才能重新开始其工作。幸运的是,已经做了很多工作,使之成为建议的通常的开始

start on runlevel [2345]

同样,在某些情况下,您还需要一些东西来保持运行直到网络断开(例如dbus / network-manager)。为此,你想要

stop on deconfiguring-networking

这是在关闭的后期发出的事件,该事件也将被阻止,直到使用它的所有作业完全完成其状态转换为止。


您的意思start on starting ... 是让我的关闭挂钩停止任何事情都没有多大意义。 start on starting rc RUNLEVEL=[016]会更有意义。也许task在那里扔了进去,以确保它可以在其他事物运行之前完成。
Tejay Cardon

0

怪胎,非常感谢您的帮助。

同时,我尝试了该start on runlevel [016]方法,但是它没有用,我想我理解为什么:

确实已经启动了该作业,但是直到该作业的任务完成后,关闭过程才被阻止。我现在非常确定,这些事件startingstopping是可以在作业定义中用来阻止其他作业的唯一事件,我认为这就是Upstart手册试图告诉我们的。因此,使用runlevel事件决不会导致阻塞其他作业或关闭进程。因此,这对我的目的没有用。

相反,我似乎有两种可能性:

  1. 按照您的建议之一,找出相应应用程序所需的所有工作,并将所有工作包括在脚本的启动事件中,如下所示:

    start on stopping job1 or stopping job2 or ...
    

    这是一项艰巨的工作,我认真考虑要转储作业列表并通过sed运行它,以自动为我的作业生成一个开始节,其中包括通常在系统上运行的所有作业。

    这样做的好处是,即使有人手动停止了其中一个前提条件(相对于通过运行级别更改/关闭/重启来停止前提条件之一),各个应用程序也会被关闭。

  2. 找到一个在重新启动/关闭系统时将首先停止的作业(我们将此作业称为“ FirstJob”),并在如下节中使用该作业:

    start on stopping FirstJob
    

    主要缺点是我不知道是否存在这样的工作,并且该工作是否真的取决于相应应用程序实际依赖的所有其他工作(在这种情况下,“取决于其他工作”意味着“将被停止完全在其他工作开始停止之前”)。

我不确定这两种可能性中哪一种更好。


sed如果我在你的鞋子里,我现在就在写剧本。
geekosaur 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.