0

多年来,我们一直将流程监控/控制脚本作为我们应用程序的一部分。脚本的默认行为是守护自己。通常,脚本是由非特权用户启动的。由于我不会详细说明的原因,我们需要保留脚本和此行为。

OSX系统上,我们通常通过 Apple 提供的/usr/libexec/StartupItemContext启动脚本让脚本在后台自行重启。这将我们的进程置于 Mach StartupItem引导上下文而不是登录引导上下文中。这是必要的,因为如果没有上下文切换,如果用户注销时(这通常也是必要的),脚本将失去对目录服务、getpwuid()、DNS 服务等的访问权限。守护脚本的原始内部行基本上看起来像这样(在 perl 中):

my $cmd = "/usr/libexec/StartupItemContext myscript @Commandline > logs/startup 2>&1" ;         
system( "$cmd &") ;
exit 0 ;

OSX Yosemite出现时,那个StartupItemContext脚本消失了,所以我们切换到直接调用launchctl

my $cmd = "/usr/launchctl bsexec / myscript @Commandline > logs/startup 2>&1" ;         
system( "$cmd &") ;
exit 0 ;

然而,随着最近的OSX 10.10.3升级,launchctl 的bsexec命令突然需要 root 权限:

% launchctl bsexec
This subcommand requires root privileges: bsexec
% 

这为我们创造了一个令人瞩目的问题,即非特权用户无法再让我们的监视/控制脚本自行守护进程。

看起来遇到了这个问题,并通过替换的补丁解决了这个问题

/bin/launchctl bsexec /

nohup

这可能适用于 Glassfish 实现,但我不认为我们适合。尽管我不明白这一点 - 即为什么简单的 SIGHUP 阻塞会阻止退役登录引导上下文中的进程丢失服务 - 它似乎也不适用于我们需要的所有系统服务的测试.

什么是在OSX上从非特权的马赫“登录”引导上下文开始守护进程的新规范方法,而不会在用户注销时失去对关键系统服务(如 DNS 等)的访问权限?

4

1 回答 1

3

不幸的是,“来自非特权的马赫“登录”引导上下文”不太可能有“规范的方式”。唯一规范的方法是通过 launchd 按需启动服务。甚至几乎不支持“bsexec”,也几乎没有文档记录。以我的经验,不可能跟上 OS X 的变化并且从不重新设计您的启动系统。我重新设计了所有其他版本的守护程序系统,因为 Apple 破坏了它,而且他们将继续破坏它。唯一的答案是继续努力使您的要求更简单。但几乎任何想要一直运行而不是按需运行的流程都直接违反了 Apple 的声明意图,因此它往往会中断。

Apple 给出的解决方案是创建一个 LaunchDaemon 并UserName在您的launchd plist 中为其分配一个。您必须以特权启动,然后切换到用户(并且它需要是固定用户,而不是“登录用户”,因为那将是 LaunchAgent)。您无法通过这种方式升级您的访问权限。你不能自己守护(再次,规范的答案是:不要那样做。请参阅 launchd.plist 手册页。)

我怀疑 Glassfishnohup解决方案只是一种躲闪,实际上并没有将它们置于 Mach 上下文中。他们只是想避免在父 shell 退出时被杀死。那可能对你没有帮助。

根据我的经验,最强大的解决方案是多部分的。您最终得到一个作为系统 LaunchDaemon(使用 KeepAlive)运行的部分,以及另一个作为用户 LaunchAgent 的部分,您让它们通过 IPC 进行通信,以便您可以访问您需要执行的每个活动所需的上下文. 是的,这通常实现起来要复杂得多。更简单的解决方案往往不起作用。

当然,你必须不断地问自己“有没有什么方法可以通过按照 Apple 的要求做事来实现这一目标。” 这意味着强烈首选 XPC,其次是按需 LaunchDaemons 和 LaunchAgents。如果您构建您的系统以使用 XPC 组件,您可能会在更多的 OS X 升级中幸存下来。您发现不使用这些部件的任何工作都可能需要在 10.11 中再次修复。

于 2015-04-21T23:39:17.307 回答