2
0
mirror of https://opendev.org/x/pyghmi synced 2025-01-29 04:17:35 +00:00

Do not count empty SOL data as keepalive data

If the console layer sends an SOL payload with zero data (which is
valid to do) the session object would treat that as keeping the
session alive on the BMC side.  Many BMCs do not consider empty
SOL payload packets toward session activity.  Accomodate by having
the keepalive deferral not be triggered by such packets.

Change-Id: I8d278dbc48fae296c754ce9bc8f05bc92b560374
This commit is contained in:
Jarrod Johnson 2014-02-02 09:23:30 -05:00
parent 02848d66b7
commit e4c76de082
2 changed files with 27 additions and 8 deletions

View File

@ -167,6 +167,10 @@ class Console(object):
return session.Session.wait_for_rsp(timeout=timeout)
def _sendpendingoutput(self):
self._sendoutput(self.pendingoutput)
self.pendingoutput = ""
def _sendoutput(self, output):
self.myseq += 1
self.myseq &= 0xf
if self.myseq == 0:
@ -176,22 +180,26 @@ class Console(object):
self.ackedseq,
self.ackedseq,
self.sendbreak)
payload += self.pendingoutput
self.lasttextsize = len(self.pendingoutput)
self.pendingoutput = ""
payload += output
self.lasttextsize = len(output)
needskeepalive = False
if self.lasttextsize == 0:
needskeepalive = True
self.awaitingack = True
payload = struct.unpack("%dB" % len(payload), payload)
self.lastpayload = payload
self.send_payload(payload)
self.send_payload(payload, needskeepalive=needskeepalive)
def send_payload(self, payload, payload_type=1, retry=True):
def send_payload(self, payload, payload_type=1, retry=True,
needskeepalive=False):
while not (self.connected or self.broken):
session.Session.wait_for_rsp(timeout=10)
if not self.ipmi_session.logged:
raise exc.IpmiException('Session no longer connected')
self.ipmi_session.send_payload(payload,
payload_type=payload_type,
retry=retry)
retry=retry,
needskeepalive=needskeepalive)
def _print_info(self, info):
self._print_data({'info': info})
@ -276,6 +284,8 @@ class Console(object):
newtext = struct.pack("B"*len(newtext), *newtext)
self.pendingoutput = newtext + self.pendingoutput
self._sendpendingoutput()
if len(self.pendingoutput) > 0:
self._sendpendingoutput()
elif self.awaitingack: # session marked us as happy, but we are not
#this does mean that we will occasionally retry a packet
#sooner than retry suggests, but that's no big deal

View File

@ -450,7 +450,16 @@ class Session(object):
retry=retry, delay_xmit=delay_xmit)
def send_payload(self, payload=None, payload_type=None, retry=True,
delay_xmit=None):
delay_xmit=None, needskeepalive=False):
"""Send payload over the IPMI Session
:param needskeepalive: If the payload is expected not to count as
'active' by the BMC, set this to True
to avoid Session considering the
job done because of this payload.
Notably, 0-length SOL packets
are prone to confusion.
"""
if payload is not None and self.lastpayload is not None:
#we already have a packet outgoing, make this
# a pending payload
@ -543,7 +552,7 @@ class Session(object):
self.netpacket = struct.pack("!%dB" % len(message), *message)
#advance idle timer since we don't need keepalive while sending packets
#out naturally
if self in Session.keepalive_sessions:
if self in Session.keepalive_sessions and not needskeepalive:
Session.keepalive_sessions[self]['timeout'] = _monotonic_time() + \
25 + (random.random() * 4.9)
self._xmit_packet(retry, delay_xmit=delay_xmit)