1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#
# gensio test utilities
#
# This file contains some classes and functions useful for testing
# gensio handling
#
import os
import tempfile
import utils
import signal
import time
ipmisol_port = 9002
default_ipmisim_emu = """
mc_setbmc 0x20\n
\n
mc_add 0x20 0 no-device-sdrs 0x23 9 8 0x9f 0x1291 0xf02 persist_sdr\n
sel_enable 0x20 1000 0x0a\n
\n
mc_enable 0x20\n
"""
default_ipmisim_config = """
name "ser2net_sim"\n
\n
set_working_mc 0x20\n
\n
startlan 1\n
addr localhost %d\n
\n
# Maximum privilege limit on the channel.\n
priv_limit admin\n
\n
# Allowed IPMI 1.5 authorization types\n
allowed_auths_callback none md2 md5 straight\n
allowed_auths_user none md2 md5 straight\n
allowed_auths_operator none md2 md5 straight\n
allowed_auths_admin none md2 md5 straight\n
\n
# guid for IPMI 2.0 authorization You can also use a string\n
guid a123456789abcdefa123456789abcdef\n
\n
endlan\n
\n
sol "/dev/ttyPipeB0" 115200 nortscts\n
\n
# Start startcmd at startup? Default is false.\n
startnow false\n
\n
# Now add some users. User 0 is invalid, user 1 is the special "anonymous"\n
# user and cannot take a username. Note that the users here are only\n
# used if the persistent user config doesn't exist.\n
# # valid name passw priv-lim max-sess allowed-auths (ignored)\n
user 1 true "" "test" user 10 none md2 md5 straight\n
user 2 true "ipmiusr" "test" admin 10 none md2 md5 straight\n
""" % (ipmisol_port)
class IPMISimDaemon:
"""Create an IPMI Sim daemon instance and start it up
ipmi_sim is started with the given config data as a config file
The IPMISIM_EXEC environment variable can be set to tell this code
to run ipmi_sim with a specific path.
"""
def __init__(self, o, configdata = None, emudata = None, extra_args = ""):
"""Create a running ipmisim program
The given config data is written to a file and used as the config file.
It is started with the -r and -d options set, you can supply extra
options if you like as a string.
"""
prog = os.getenv("IPMISIM_EXEC")
if (not prog):
prog = "ipmi_sim"
if not configdata:
configdata = default_ipmisim_config
if not emudata:
emudata = default_ipmisim_emu
self.cfile = tempfile.NamedTemporaryFile(mode="w+")
self.cfile.write(configdata)
self.cfile.flush()
self.efile = tempfile.NamedTemporaryFile(mode="w+")
self.efile.write(emudata)
self.efile.flush()
self.o = o
args = "stdio," + prog + " -p -c " + self.cfile.name + " -f " + self.efile.name + " " + extra_args
if (utils.debug):
print("Running: " + args)
self.handler = utils.HandleData(o, args, name="ipmisim daemon")
self.io = self.handler.io
self.io.closeme = True
self.io.open_s()
# Uncomment the following or set it yourself to get output from
# the ipmisim daemon printed.
#self.handler.debug = 2
self.pid = utils.remote_id_int(self.io)
self.handler.set_waitfor("> ")
if (self.handler.wait_timeout(2000) == 0):
raise Exception("Timeout waiting for ipmi_sim to start")
self.handler.ignore_input = True
# Leave read on so if we enable debug we can see output from the
# daemon.
self.io.read_cb_enable(True)
return
def __del__(self):
if (self.handler):
self.terminate()
return
def signal(self, sig):
""""Send a signal to ipmi_sim"""
os.kill(self.pid, sig)
return
def terminate(self):
"""Terminate the running ipmi_sim
This closes the io and sends a SIGTERM to ipmi_sim and waits
a bit for it to terminate. If it does not terminate, send
SIGTERM a few more times. If it still refuses to close, send
a SIGKILL. If all that fails, raise an exception.
"""
if (self.handler.debug or utils.debug):
print("Terminating")
if self.io.closeme:
self.handler.close()
count = 10
while (count > 0):
if (count < 6):
self.signal(signal.SIGTERM)
else:
self.signal(signal.SIGKILL)
# It would be really nice if waitpid had a timeout options,
# in absence of that simulate it, sort of.
subcount = 500
while (subcount > 0):
time.sleep(.01)
pid, rv = os.waitpid(self.pid, os.WNOHANG)
if (pid > 0):
self.handler = None
return
subcount -= 1
count -= 1
raise Exception("ipmisim did not terminate");
|