@@ -3,6 +3,8 @@
#
# SPDX-License-Identifier: MIT
#
+import hashlib
+import subprocess
import os
import time
from oeqa.core.decorator import OETestTag
@@ -84,10 +86,24 @@ class GccSelfTestBase(OESelftestTestCase, OEPTestResultTestCase):
# validate that SSH is working
status, _ = qemu.run("uname")
self.assertEqual(status, 0)
- qemu.run('echo "MaxStartups 75:30:100" >> /etc/ssh/sshd_config')
- qemu.run('service sshd restart')
- return self.run_check(*args, ssh=qemu.ip, **kwargs)
+ # Increase MaxSessions to accommodate concurrent GCC test shards sharing
+ # the SSH master connection.
+ qemu.run('echo "MaxSessions 200" >> /etc/ssh/sshd_config')
+ status, output = qemu.run('[ ! -f /var/run/sshd.pid ] || kill -HUP $(cat /var/run/sshd.pid)')
+ if status != 0:
+ raise Exception(f"sshd reload failed (rc={status}): {output}")
+
+ # With ControlPersist=yes, never times out on its own, so close it
+ # explicitly once all test shards have finished.
+ controlpath = "/tmp/oe-gcc-ssh-" + hashlib.sha1(get_bb_var("B", "gcc-runtime").encode()).hexdigest()[:12]
+ try:
+ return self.run_check(*args, ssh=qemu.ip, **kwargs)
+ finally:
+ subprocess.run(["ssh", "-O", "exit",
+ "-o", "ControlPath={0}".format(controlpath),
+ "root@{0}".format(qemu.ip)],
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
@OETestTag("toolchain-user")
class GccCrossSelfTest(GccSelfTestBase):
@@ -80,6 +80,7 @@ python check_prepare() {
return "\n".join(content)
def generate_remote_ssh_linux_config(d):
+ import hashlib, os
content = []
content.append('load_generic_config "unix"')
content.append('process_multilib_options ""')
@@ -87,8 +88,19 @@ python check_prepare() {
content.append("set_board_info username {0}".format(d.getVar("TOOLCHAIN_TEST_HOST_USER")))
port = d.getVar("TOOLCHAIN_TEST_HOST_PORT")
- content.append("set_board_info rsh_prog \"/usr/bin/ssh -p {0} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR \"".format(port))
- content.append("set_board_info rcp_prog \"/usr/bin/scp -P {0} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR \"".format(port))
+
+ # Use SSH multiplexing to share one master connection across GCC tests.
+ # Keep the master alive until the selftest explicitly closes it.
+ # Use a per-build ControlPath to avoid conflicts between builds.
+ controlpath = "/tmp/oe-gcc-ssh-" + hashlib.sha1(d.getVar("B").encode()).hexdigest()[:12]
+ # remove stale socket left by a previous stopped run of this build
+ if os.path.exists(controlpath):
+ os.remove(controlpath)
+ rsh_mux = " -o ControlMaster=auto -o ControlPath={0} -o ControlPersist=yes".format(controlpath)
+ rcp_mux = " -o ControlMaster=no -o ControlPath={0}".format(controlpath)
+
+ content.append("set_board_info rsh_prog \"/usr/bin/ssh -p {0} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR{1} \"".format(port, rsh_mux))
+ content.append("set_board_info rcp_prog \"/usr/bin/scp -P {0} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR{1} \"".format(port, rcp_mux))
return "\n".join(content)