2
0
mirror of https://opendev.org/x/pyghmi synced 2025-03-19 18:07:45 +00:00

Change session timer to monotonic when possible

Previously the ipmi session was using time.time().  This means
that retries and keepalives could be thrown off by things like ntp
or manual time corrections.

Ideally, we'd use the baked in time.monotonic(), but that doesn't exist
aside from python 3.3

Change-Id: Ia00026cef6df214f9463909309de44767c3752b5
This commit is contained in:
Jarrod Johnson 2013-07-18 16:20:44 -04:00
parent 0e8ca33842
commit 86a2d39db7
2 changed files with 30 additions and 14 deletions

View File

@ -37,6 +37,22 @@ initialtimeout = 0.5 # minimum timeout for first packet to retry in any given
# in case of congestion
def _monotonic_time():
"""Provides a monotonic timer
This code is concerned with relative, not absolute time.
This function facilitates that prior to python 3.3
"""
# Python does not provide one until 3.3, so we make do
# for most OSes, os.times()[4] works well.
# for microsoft, GetTickCount64
if (os.name == "posix"):
return os.times()[4]
else: # last resort, non monotonic time
return time.time()
#TODO(jbjohnso): Windows variant
def _aespad(data):
"""ipmi demands a certain pad scheme,
per table 13-20 AES-CBC encrypted payload fields.
@ -419,8 +435,8 @@ class Session:
#advance idle timer since we don't need keepalive while sending packets
#out naturally
if self in Session.keepalive_sessions:
Session.keepalive_sessions[self]['timeout'] = time.time() + 25 + \
(random.random() * 4.9)
Session.keepalive_sessions[self]['timeout'] = _monotonic_time() + \
25 + (random.random() * 4.9)
self._xmit_packet(retry)
def _ipmi15authcode(self, payload, checkremotecode=False):
@ -532,8 +548,8 @@ class Session:
self.logged = 1
Session.keepalive_sessions[self] = {}
Session.keepalive_sessions[self]['ipmisession'] = self
Session.keepalive_sessions[self]['timeout'] = time.time() + 25 + \
(random.random() * 4.9)
Session.keepalive_sessions[self]['timeout'] = _monotonic_time() + \
25 + (random.random() * 4.9)
call_with_optional_args(
self.onlogon, {'success': True}, self.onlogonargs)
@ -603,7 +619,7 @@ class Session:
#Instance C gets to go ahead of Instance A, because
#Instance C can get work done, but instance A cannot
curtime = time.time()
curtime = _monotonic_time()
# There ar a number of parties that each has their own timeout
# The caller can specify a deadline in timeout argument
# each session with active outbound payload has callback to
@ -1066,7 +1082,7 @@ class Session:
Session.waiting_sessions[self] = {}
Session.waiting_sessions[self]['ipmisession'] = self
Session.waiting_sessions[self]['timeout'] = self.timeout + \
time.time()
_monotonic_time()
Session.pending += 1
if self.sockaddr:
Session.socket.sendto(self.netpacket, self.sockaddr)

View File

@ -23,7 +23,7 @@ understand how the ipmi_command class workes.
import os
import sys
from ipmi.command import Command
from ipmi import command
password = os.environ['IPMIPASSWORD']
os.environ['IPMIPASSWORD'] = ""
if (len(sys.argv) < 3):
@ -32,23 +32,23 @@ if (len(sys.argv) < 3):
sys.exit(1)
bmc = sys.argv[1]
userid = sys.argv[2]
command = sys.argv[3]
cmmand = sys.argv[3]
args = None
if len(sys.argv) >= 5:
args = sys.argv[4:]
ipmicmd = Command(bmc=bmc, userid=userid, password=password)
if command == 'power':
ipmicmd = command.Command(bmc=bmc, userid=userid, password=password)
if cmmand == 'power':
if args:
print ipmicmd.set_power(args[0], wait=True)
else:
print ipmicmd.get_power()
elif command == 'bootdev':
elif cmmand == 'bootdev':
if args:
print ipmicmd.set_bootdev(args[0])
else:
print ipmicmd.get_bootdev()
elif command == 'raw':
elif cmmand == 'raw':
netfn = args[0]
command = args[1]
cmmand = args[1]
data = args[2:]
print ipmicmd.raw_command(netfn=netfn, command=command, data=data)
print ipmicmd.raw_command(netfn=netfn, command=cmmand, data=data)