diff --git a/ironic/drivers/modules/console_utils.py b/ironic/drivers/modules/console_utils.py index 84eae03e62..5af5835884 100644 --- a/ironic/drivers/modules/console_utils.py +++ b/ironic/drivers/modules/console_utils.py @@ -305,9 +305,11 @@ def start_socat_console(node_uuid, port, console_cmd): console_host = CONF.console.socat_address if netutils.is_valid_ipv6(console_host): - arg = 'TCP6-LISTEN:%(port)s,bind=[%(host)s],reuseaddr' + arg = ('TCP6-LISTEN:%(port)s,bind=[%(host)s],reuseaddr,fork,' + 'max-children=1') else: - arg = 'TCP4-LISTEN:%(port)s,bind=%(host)s,reuseaddr' + arg = ('TCP4-LISTEN:%(port)s,bind=%(host)s,reuseaddr,fork,' + 'max-children=1') args.append(arg % {'host': console_host, 'port': port}) diff --git a/ironic/tests/unit/drivers/modules/test_console_utils.py b/ironic/tests/unit/drivers/modules/test_console_utils.py index 6355ad0494..4c83fb169c 100644 --- a/ironic/tests/unit/drivers/modules/test_console_utils.py +++ b/ironic/tests/unit/drivers/modules/test_console_utils.py @@ -467,13 +467,15 @@ class ConsoleUtilsTestCase(db_base.DbTestCase): def test_start_socat_console_check_arg_bind_addr_default_ipv4(self): self.config(my_ip='10.0.0.1') args = self._test_start_socat_console_check_arg() - self.assertIn('TCP4-LISTEN:%s,bind=10.0.0.1,reuseaddr' % + self.assertIn('TCP4-LISTEN:%s,bind=10.0.0.1,reuseaddr,fork,' + 'max-children=1' % self.info['port'], args) def test_start_socat_console_check_arg_bind_addr_ipv4(self): self.config(socat_address='10.0.0.1', group='console') args = self._test_start_socat_console_check_arg() - self.assertIn('TCP4-LISTEN:%s,bind=10.0.0.1,reuseaddr' % + self.assertIn('TCP4-LISTEN:%s,bind=10.0.0.1,reuseaddr,fork,' + 'max-children=1' % self.info['port'], args) @mock.patch.object(os.path, 'exists', autospec=True) diff --git a/releasenotes/notes/socat-respawn-de9e8805c820a7ac.yaml b/releasenotes/notes/socat-respawn-de9e8805c820a7ac.yaml new file mode 100644 index 0000000000..980e0f9daf --- /dev/null +++ b/releasenotes/notes/socat-respawn-de9e8805c820a7ac.yaml @@ -0,0 +1,9 @@ +--- +fixes: + - Ironic does not monitor the socat proxy started for serial console + access. The socat process would exit on client disconnect, which + would (a) leave a zombie socat process in the process table and (b) + disable any subsequent serial console connections. Fixed the issue by + updating Ironic to call socat with the ``fork,max-children=1`` options, + which makes socat persist and accept multiple connections (but only one + at a time). See https://storyboard.openstack.org/#!/story/2005024.