From 0b7f6b13951125578faa65639851b1765a2e4a7c Mon Sep 17 00:00:00 2001 From: Markus Hilger Date: Fri, 14 Aug 2026 14:07:49 +0200 Subject: [PATCH] Tidy three loose ends around sharing a session Closing a console gives up its claim on the session, and that talks to the bmc, so let it fail the same way the console's own deactivate is already allowed to. kg was left as the caller passed it in both the register key and the reuse check, so the mismatch fixed for the name and password still applied to it. The count for a new socket was taken before binding it and before the io task was known to be up. Take it last, once nothing is left that can still fail. --- confluent_server/aiohmi/ipmi/console.py | 7 ++++++- confluent_server/aiohmi/ipmi/private/session.py | 10 +++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/confluent_server/aiohmi/ipmi/console.py b/confluent_server/aiohmi/ipmi/console.py index 6f3abfeb..ab463eb5 100644 --- a/confluent_server/aiohmi/ipmi/console.py +++ b/confluent_server/aiohmi/ipmi/console.py @@ -217,7 +217,12 @@ class Console(object): self.ipmi_session = None if sess.sol_handler is not None and sess.sol_handler.__self__ is self: sess.sol_handler = None - await sess.logout() + try: + await sess.logout() + except exc.IpmiException: + # A bmc that has stopped answering must not be what makes + # closing a console fail, as for the deactivate above + pass async def close(self): """Shut down an SOL session""" diff --git a/confluent_server/aiohmi/ipmi/private/session.py b/confluent_server/aiohmi/ipmi/private/session.py index 30caa535..6726a4e6 100644 --- a/confluent_server/aiohmi/ipmi/private/session.py +++ b/confluent_server/aiohmi/ipmi/private/session.py @@ -390,7 +390,6 @@ class Session(object): # Rather than wait until send() to bind, bind now so that we have # a port number allocated no matter what tmpsocket.bind(('', 0)) - cls.socketpool[tmpsocket] = 1 else: tmpsocket.bind(server[4]) iosockets.append(tmpsocket) @@ -413,6 +412,10 @@ class Session(object): initevt = asyncio.Event() iothreadwaiters.append(initevt) await initevt.wait() + if server is None: + # Take the count last: one taken for a socket no session ever + # received is one nobody is left to give back + cls.socketpool[tmpsocket] = 1 return tmpsocket def _sync_login(self, response): @@ -462,7 +465,8 @@ class Session(object): keepalive=True): trueself = None forbidsock = [] - sesskey = (bmc, _credkey(userid), _credkey(password), port, kg) + sesskey = (bmc, _credkey(userid), _credkey(password), port, + _credkey(kg)) for res in socket.getaddrinfo(bmc, port, 0, socket.SOCK_DGRAM): sockaddr = res[4] if ipv6support and res[0] == socket.AF_INET: @@ -480,7 +484,7 @@ class Session(object): if (self.bmc == bmc and self.userid == _credkey(userid) and self.password == _credkey(password) - and self.kgo == kg): + and _credkey(self.kgo) == _credkey(kg)): trueself = self break # ok, the candidate seems to be working, but does not match