制作关机钩子的最佳方法是什么?

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

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

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

  • 在upstart中没有一般的关闭事件
  • 在作业定义中使用类似start on starting shutdown的节
  • 在作业定义中使用类似于start on runlevel [06S]的节
  • 在作业定义中start on starting runlevel [06S]使用类似start on starting runlevel [06S]的节
  • 在作业定义中使用像start on stopping runlevel [!06S]一样的节start on stopping runlevel [!06S]

根据这些建议,出现以下问题:

  • 在Ubuntu的新贵中是否存在或没有一般的关闭事件?
  • 实施“关闭挂钩”的推荐方法是什么?
  • 什么时候事件运行级别[x]被触发; 进入运行级别或进入运行级别时是这样的吗?
  • 我们可以start on starting runlevel [x]使用诸如start on starting runlevel [x]东西,还是start on stopping runlevel [x]
  • 什么是我的问题的最佳解决方案?

非常感谢你

startingrunlevel是单独的事件,因此你无法有意义地说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.

为了在作业停止时停止关机,你需要使用:

 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 

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

Geekosaur,非常感谢你的帮助。

与此同时,我尝试了start on runlevel [016]方法的开始,但它没有用,我想我理解为什么:

该作业确实已启动,但在作业任务完成之前,关闭过程尚未被阻止。 我现在非常确定事件的startingstopping是唯一可以在作业定义中用来阻止其他工作的事件,我认为这是Upstart的手册试图告诉我们的。 因此,使用运行级别事件永远不会导致阻止其他作业或关闭进程; 因此,它对我的​​目的毫无用处。

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

  1. 根据您的一个提议,找出所有相关应用程序所需的作业,并将其全部包含在脚本的启动事件中,如下所示:

     start on stopping job1 or stopping job2 or ... 

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

    优点是即使有人手动停止其中一个先决条件(而不是通过运行级别更改/关闭/重新启动来停止它们),相应的应用程序也将被关闭。

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

     start on stopping FirstJob 

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

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