追加読書

追加読書

次のサービスを設定しました。

[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' [email protected] && exit -1)"
Restart=on-failure

[Install]
WantedBy=multi-user.target    

何らかの理由でプロセスがゼロ以外のシャットダウンで終了すると、コマンドはメールを送信mailしません。これは、scollectorコマンドラインから実行または呼び出すとうまく機能します。/bin/shSTDOUTとSTDERRをキャプチャしましたが、mailエラーは発生しません。中には何もありませんmaillog

何を提供しますか?なぜ電子メールを送信しないのですか?

答え1

/usr/bin/mailデュアルforkデーモンを実行してsendmail電子メールを送信します。プロセスsendmailは再所有されているため、init通常は元の親プロセスで発生したことに影響されません。ただし、再所有された孫が依然として元のサービスと同じcgroupにあるsystemdの場合は例外です。何かを解体すると、systemd再所有したプロセスを含むcgroup内のすべてのプロセスが終了しますsendmail

コマンドmail自体は正しく実行されましたが、sendmailそのタスクを実行する機会がある前にsystemdによって終了しました。

KillModeUnitセクションで(デフォルト)を設定してprocessこの問題を解決できますcontrol-group。これにより、systemd直接トリガーされたプロセスのみが終了します。

面白いことは、私がこれを使用する方法で偶然発見したことですstracestrace通常は何も表示されませんが、mail使用すると突然動作し始めましたstrace -fstrace -fすべての子供と孤児孫が完了するまで、基本的なプロセスは維持されます。

答え2

質問者は問題を指摘しましたが、xyrソリューションはジレンマであり、xyrはダイナミクスを誤って説明しています。

このmailコマンドは真ですいいえデュアルフォークを実行します。一度だけフォークされ、sendmail shimプロセスはその直系の子であり、何も再び親にしません。ただwaitpid()去る前に、その子供にサービスを提供するかどうかを選択します。

sendmail shim自体も同様です。二重フォークにはなりません。一部のMTSではまったくフォークが発生しません。他のシステムでは、一度だけ分岐し、設定可能な「配信モード」オプションに依存するかどうかを選択します。

この問題を解決する2つの正しい方法があります。

  1. mailxロギングと正規化オプションのセットですsendwait。 sendmail shimサブプロセスが完了するのをmailx待つと、非同期キューの問題は具体的に解決されます。 (残念ながら、このオプションは少なくとも1986年から存在し、mailxSVIDに文書化されていますが、bsd-mailxにはこのオプションはありませんが、heirloom-mailxにはあります。)
  2. まだ使用中でない場合は、同期キュー/配信モードを使用するために使用中のMTSを設定します。
    • netqmailを使用している場合、何もしません。 Netqmailのsendmail shimは常にキューにあり、同期され、直接チェーンロードされ、qmail-injectまったくqmail-queue分岐しません。
    • Postfixを使用している場合は何もしません。 Postfixのsendmail shimは常にキューにあり同期され、一度分岐して終了postdropする前に完了するのを待ちます。
    • eximには-odfコマンドラインオプションがあります。

追加読書

関連情報