我配置了以下服务:
[Unit]
Description=SCollector
After=NetworkManager.service
[Service]
Type=simple
ExecStart=/bin/sh -c "/opt/scollector/scollector /opt/scollector/collectors || (echo '' | /usr/bin/mail -s 'scollector died' jharvey@stackoverflow.com && exit -1)"
Restart=on-failure
[Install]
WantedBy=multi-user.target 由于某种原因,当mail进程以非-0形式退出时,scollector命令从不发送任何邮件。这可以在命令行、/bin/sh调用和所有程序上运行。我捕获了mail的STDOUT和STDERR,它没有抛出任何错误。在maillog中什么都没有。
怎么回事?为什么它不发邮件?
发布于 2015-09-22 02:04:14
/usr/bin/mail执行双fork来守护发送电子邮件的sendmail。这个sendmail proc被重新拥有给init,因此通常它不会受到与原始父服务器发生的任何事情的影响--除非在systemd情况下,再生孙辈仍然与原始服务位于同一个cgroup中。当systemd分解时,它会杀死cgroup中的所有进程,包括重新拥有的sendmail进程。
mail命令本身运行良好,但sendmail在有机会完成任务之前就被systemd杀死了。
您可以通过将KillMode设置为Unit节中的process (默认为control-group)来解决这一问题。这将导致systemd只杀死它直接触发的进程。
有趣的是,我偶然发现这是通过使用strace。一个普通的strace没有透露任何信息,但是mail在使用strace -f时突然开始工作。strace -f导致了这个主要过程的继续存在,直到所有的孩子和孤儿的孙辈都结束了。
发布于 2015-10-04 12:30:27
发问者已经发现了问题;但是xyr解决方案是一个错误,而xyr对力学的描述是不正确的。
mail命令不执行双叉。它只分叉一次,sendmail进程是它的直接子进程,没有对任何东西进行修复。它只需在退出之前选择是否为该子waitpid()。
sendmail本身也是如此。它不是双叉的。在某些MTSes上,它甚至根本不分叉。在其他情况下,它只分叉一次,并选择是否等待取决于某个可配置的“传递模式”选项。
解决这个问题的正确方法有两方面:
mailx的S文档化和标准化的sendwait选项。这具体解决了异步排队的问题,让mailx等待sendmail子进程完成。(遗憾的是,尽管这个选项至少从1986年开始就已经出现,并且在SVID中为mailx记录在案,但bsd-mailx没有。传家宝-邮件有它。)qmail-inject直接链式加载到qmail-queue,根本没有分叉。postdrop完成,然后退出。-odf命令行选项。https://unix.stackexchange.com/questions/231200
复制相似问题