From f369fdd3341f2868bbc84257cc1123900864e3ab Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Fri, 15 Feb 2019 11:35:54 -0500 Subject: [PATCH] ensure that socat serial proxy keeps running Socat as configured would exit on client disconnect. Since there was no active process monitoring, the process would (a) become a zombie, and (b) would not restart, which would disable console access. This commits adds the fork,max-children=1 parametesr to the socat call, which makes socat persistent until it is explicitly killed. Change-Id: I612cd9bca403b7a77ad3e671c1fdadd55353d5f7 Story: 2005024 Task: 29503 --- ironic/drivers/modules/console_utils.py | 6 ++++-- ironic/tests/unit/drivers/modules/test_console_utils.py | 6 ++++-- releasenotes/notes/socat-respawn-de9e8805c820a7ac.yaml | 9 +++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 releasenotes/notes/socat-respawn-de9e8805c820a7ac.yaml 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.