2015-07-15

RHEL7: `firewalld' dies at `reload'

firewalld の reload が失敗する。正確には、reload は成功するが、firewalld が死ぬ。しかも死ぬのは決まって二回目の reload で、初回は上手くいく。

# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.1 (Maipo)

# systemctl restart firewalld ; echo $?
0

# systemctl status firewalld ; echo $?
firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
   Active: active (running) since Wed 2015-07-15 18:12:16 JST; 5s ago
  Process: 4566 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
 Main PID: 4597 (firewalld)
   CGroup: /system.slice/firewalld.service
           `-4597 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid

Jul 15 18:12:16 rhel7 systemd[1]: Starting firewalld - dynamic firewall dae.....
Jul 15 18:12:16 rhel7 systemd[1]: Started firewalld - dynamic firewall daemon.
Hint: Some lines were ellipsized, use -l to show in full.
0

# systemctl reload firewalld ; echo $?
0

# systemctl status firewalld ; echo $?
firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
   Active: active (running) since Wed 2015-07-15 18:12:16 JST; 33s ago
  Process: 4924 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
 Main PID: 4597 (firewalld)
   CGroup: /system.slice/firewalld.service
           `-4597 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid

Jul 15 18:12:16 rhel7 systemd[1]: Starting firewalld - dynamic firewall dae.....
Jul 15 18:12:16 rhel7 systemd[1]: Started firewalld - dynamic firewall daemon.
Jul 15 18:12:27 rhel7 systemd[1]: Reloading firewalld - dynamic firewall daemon.
Jul 15 18:12:27 rhel7 systemd[1]: Reloaded firewalld - dynamic firewall daemon.
Hint: Some lines were ellipsized, use -l to show in full.
0

# systemctl reload firewalld ; echo $?
0

# systemctl status firewalld ; echo $?
firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
   Active: inactive (dead) since Wed 2015-07-15 18:12:53 JST; 3s ago
  Process: 5266 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
  Process: 4597 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS (code=killed, signal=HUP)
 Main PID: 4597 (code=killed, signal=HUP)

Jul 15 18:12:16 rhel7 systemd[1]: Starting firewalld - dynamic firewall dae.....
Jul 15 18:12:16 rhel7 systemd[1]: Started firewalld - dynamic firewall daemon.
Jul 15 18:12:27 rhel7 systemd[1]: Reloading firewalld - dynamic firewall daemon.
Jul 15 18:12:27 rhel7 systemd[1]: Reloaded firewalld - dynamic firewall daemon.
Jul 15 18:12:53 rhel7 systemd[1]: Reloading firewalld - dynamic firewall daemon.
Jul 15 18:12:53 rhel7 systemd[1]: Reloaded firewalld - dynamic firewall daemon.
Hint: Some lines were ellipsized, use -l to show in full.
3

systemd 経由ではなく、「firewall-cmd --reload」で reload すると問題は起こらない。

# systemctl restart firewalld ; echo $?
0

# systemctl status firewalld ; echo $?
firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
   Active: active (running) since Wed 2015-07-15 18:13:22 JST; 2s ago
  Process: 5266 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
 Main PID: 5271 (firewalld)
   CGroup: /system.slice/firewalld.service
           `-5271 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid

Jul 15 18:13:22 rhel7 systemd[1]: Starting firewalld - dynamic firewall dae.....
Jul 15 18:13:22 rhel7 systemd[1]: Started firewalld - dynamic firewall daemon.
Hint: Some lines were ellipsized, use -l to show in full.
0

# firewall-cmd --reload ; echo $?
success
0

# systemctl status firewalld ; echo $?
firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
   Active: active (running) since Wed 2015-07-15 18:13:22 JST; 18s ago
  Process: 5266 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
 Main PID: 5271 (firewalld)
   CGroup: /system.slice/firewalld.service
           `-5271 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid

Jul 15 18:13:22 rhel7 systemd[1]: Starting firewalld - dynamic firewall dae.....
Jul 15 18:13:22 rhel7 systemd[1]: Started firewalld - dynamic firewall daemon.
Hint: Some lines were ellipsized, use -l to show in full.
0

# firewall-cmd --reload ; echo $?
success
0

# systemctl status firewalld ; echo $?
firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
   Active: active (running) since Wed 2015-07-15 18:13:22 JST; 39s ago
  Process: 5266 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
 Main PID: 5271 (firewalld)
   CGroup: /system.slice/firewalld.service
           `-5271 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid

Jul 15 18:13:22 rhel7 systemd[1]: Starting firewalld - dynamic firewall dae.....
Jul 15 18:13:22 rhel7 systemd[1]: Started firewalld - dynamic firewall daemon.
Hint: Some lines were ellipsized, use -l to show in full.
0

どうやら firewalld の HUP 受信処理に問題がありそうだ。試しに firewalld プロセスに直接 HUP シグナルを送ってみると、現象が再現した。最初の HUP 処理後にシグナルハンドラーを再登録してないっぽい? (ソースコードは確認していない)

以上より、

  • 「systemctl reload firewalld」ではなく、「firewall-cmd --reload」を使うべし。
  • もしくは「systemctl restart firewalld」を使う。(但し確立中の接続は切れるかも知れない)

今後これが修正されるとしても、バージョン依存したくはないので、RHEL7 ではこれを徹底するのが良いと思う。もちろん嫌なバッドノウハウであることは認める。:-(

ググってみると、Red Hat Bugzilla には見当たらなかったが、CentOS の方で報告されていた。本家の方でも待っていればそのうち直ると思われる。


2016-05-31 追記

Red Hat Bugzilla にも登録された模様。