blob: 515fa1f4a3eb564ccdbd23a9c1bb31699bfa8774 [file] [log] [blame]
Norman James89de9162015-08-27 21:41:36 -05001#!/usr/bin/env python
2
Norman James471ab592015-08-30 22:29:40 -05003import sys
Norman James89de9162015-08-27 21:41:36 -05004import subprocess
Norman James5d78b4d2015-09-05 13:34:34 -05005from gi.repository import GObject
Norman James89de9162015-08-27 21:41:36 -05006import dbus
7import dbus.service
8import dbus.mainloop.glib
Norman James90baede2015-09-02 20:32:49 -05009import os
10import PropertyManager
Norman James471ab592015-08-30 22:29:40 -050011
Norman James9e6acf92015-09-08 07:00:04 -050012import Openbmc
13
Norman James471ab592015-08-30 22:29:40 -050014if (len(sys.argv) < 2):
15 print "Usage: system_manager.py [system name]"
16 exit(1)
17
18System = __import__(sys.argv[1])
19import Openbmc
Norman James89de9162015-08-27 21:41:36 -050020
21DBUS_NAME = 'org.openbmc.managers.System'
22OBJ_NAME = '/org/openbmc/managers/System'
Norman James471ab592015-08-30 22:29:40 -050023HEARTBEAT_CHECK_INTERVAL = 20000
Norman James89de9162015-08-27 21:41:36 -050024
Norman James89de9162015-08-27 21:41:36 -050025
26class SystemManager(dbus.service.Object):
27 def __init__(self,bus,name):
28 dbus.service.Object.__init__(self,bus,name)
Norman James5d78b4d2015-09-05 13:34:34 -050029 self.property_manager = PropertyManager.PropertyManager(bus,System.CACHE_PATH)
Norman James9e6acf92015-09-08 07:00:04 -050030
Norman James90baede2015-09-02 20:32:49 -050031 ## Signal handlers
32 bus.add_signal_receiver(self.NewBusHandler,
Norman James89de9162015-08-27 21:41:36 -050033 dbus_interface = 'org.freedesktop.DBus',
34 signal_name = "NameOwnerChanged")
Norman James9e6acf92015-09-08 07:00:04 -050035 bus.add_signal_receiver(self.HeartbeatHandler, signal_name = "Heartbeat")
Norman James362a80f2015-09-14 14:04:39 -050036 bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")
Norman James90baede2015-09-02 20:32:49 -050037
Norman James362a80f2015-09-14 14:04:39 -050038 self.current_state = ""
39 self.system_states = {}
40 self.IPMI_ID_LOOKUP = {}
41 for bus_name in System.SYSTEM_CONFIG.keys():
42 sys_state = System.SYSTEM_CONFIG[bus_name]['system_state']
43 if (self.system_states.has_key(sys_state) == False):
44 self.system_states[sys_state] = []
45 self.system_states[sys_state].append(bus_name)
46 self.SystemStateHandler("INIT")
47 print "SystemManager Init Done"
48
49
50 def SystemStateHandler(self,state_name):
51 print "Running System State: "+state_name
52 if (self.system_states.has_key(state_name)):
53 for bus_name in self.system_states[state_name]:
Norman James90baede2015-09-02 20:32:49 -050054 self.start_process(bus_name)
Norman James90baede2015-09-02 20:32:49 -050055
Norman James362a80f2015-09-14 14:04:39 -050056 if (state_name == "INIT"):
57 ## Add poll for heartbeat
58 GObject.timeout_add(HEARTBEAT_CHECK_INTERVAL, self.heartbeat_check)
Norman James9e6acf92015-09-08 07:00:04 -050059
Norman James362a80f2015-09-14 14:04:39 -050060 if (System.ENTER_STATE_CALLBACK.has_key(state_name)):
61 cb = System.ENTER_STATE_CALLBACK[state_name]
62 obj = bus.get_object(cb['bus_name'],cb['obj_name'])
63 method = obj.get_dbus_method(cb['method_name'],cb['interface_name'])
64 method()
Norman James471ab592015-08-30 22:29:40 -050065
Norman James362a80f2015-09-14 14:04:39 -050066 current_state = state_name
67
Norman James471ab592015-08-30 22:29:40 -050068 def start_process(self,bus_name):
Norman James5d78b4d2015-09-05 13:34:34 -050069 if (System.SYSTEM_CONFIG[bus_name]['start_process'] == True):
70 process_name = System.BIN_PATH+System.SYSTEM_CONFIG[bus_name]['process_name']
71 cmdline = [ ]
72 cmdline.append(process_name)
73 for instance in System.SYSTEM_CONFIG[bus_name]['instances']:
74 cmdline.append(instance['name'])
75 try:
Norman James362a80f2015-09-14 14:04:39 -050076 print "Starting process: "+" ".join(cmdline)+": "+bus_name
Norman James5d78b4d2015-09-05 13:34:34 -050077 System.SYSTEM_CONFIG[bus_name]['popen'] = subprocess.Popen(cmdline);
78 except Exception as e:
79 ## TODO: error
80 print "Error starting process: "+" ".join(cmdline)
Norman James471ab592015-08-30 22:29:40 -050081
Norman James89de9162015-08-27 21:41:36 -050082 def heartbeat_check(self):
Norman James362a80f2015-09-14 14:04:39 -050083 #print "heartbeat check"
Norman James471ab592015-08-30 22:29:40 -050084 for bus_name in System.SYSTEM_CONFIG.keys():
Norman James362a80f2015-09-14 14:04:39 -050085 if (System.SYSTEM_CONFIG[bus_name]['start_process'] == True and
86 System.SYSTEM_CONFIG[bus_name].has_key('popen')):
Norman James5d78b4d2015-09-05 13:34:34 -050087 ## even if process doesn't request heartbeat check,
88 ## make sure process is still alive
89 p = System.SYSTEM_CONFIG[bus_name]['popen']
90 p.poll()
91 if (p.returncode != None):
92 print "Process for "+bus_name+" appears to be dead"
93 self.start_process(bus_name)
94
95 ## process is alive, now check if heartbeat received
96 ## during previous interval
97 elif (System.SYSTEM_CONFIG[bus_name]['heartbeat'] == 'yes'):
98 if (System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] == 0):
99 print "Heartbeat error: "+bus_name
100 p = System.SYSTEM_CONFIG[bus_name]['popen']
101 ## TODO: error checking
102 p.poll()
103 if (p.returncode == None):
104 print "Process must be hung, so killing"
105 p.kill()
Norman James471ab592015-08-30 22:29:40 -0500106
Norman James5d78b4d2015-09-05 13:34:34 -0500107 self.start_process(bus_name)
108 else:
109 System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] = 0
Norman James362a80f2015-09-14 14:04:39 -0500110 #print "Heartbeat ok: "+bus_name
Norman James471ab592015-08-30 22:29:40 -0500111
112 return True
Norman James89de9162015-08-27 21:41:36 -0500113
Norman James90baede2015-09-02 20:32:49 -0500114 def HeartbeatHandler(self,bus_name):
Norman James362a80f2015-09-14 14:04:39 -0500115 #print "Heartbeat seen: "+bus_name
Norman James471ab592015-08-30 22:29:40 -0500116 System.SYSTEM_CONFIG[bus_name]['heartbeat_count']=1
Norman James89de9162015-08-27 21:41:36 -0500117
Norman James90baede2015-09-02 20:32:49 -0500118 def NewBusHandler(self, bus_name, a, b):
Norman James471ab592015-08-30 22:29:40 -0500119 if (len(b) > 0 and bus_name.find(Openbmc.BUS_PREFIX) == 0):
120 if (System.SYSTEM_CONFIG.has_key(bus_name)):
121 System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] = 0
Norman James362a80f2015-09-14 14:04:39 -0500122 objects = {}
123 Openbmc.get_objs(bus,bus_name,Openbmc.OBJ_PREFIX,objects)
124
125 for instance_name in objects.keys():
126 obj_path = objects[instance_name]['PATH']
127 for instance in System.SYSTEM_CONFIG[bus_name]['instances']:
128 if (instance.has_key('properties') and instance['name'] == instance_name):
129 props = instance['properties']
130 print "Load Properties: "+obj_path
131 self.property_manager.loadProperties(bus_name,obj_path,props)
132 ## create a lookup for ipmi id to object path
133 if (props.has_key('org.openbmc.SensorValue')):
134 if (props['org.openbmc.SensorValue'].has_key('ipmi_id')):
135 ipmi_id = props['org.openbmc.SensorValue']['ipmi_id']
136 ## TODO: check for duplicate ipmi id
137 self.IPMI_ID_LOOKUP[ipmi_id]=[bus_name,obj_path]
Norman James90baede2015-09-02 20:32:49 -0500138
Norman James362a80f2015-09-14 14:04:39 -0500139 ## If object has an init method, call it
140 for init_intf in objects[instance_name]['INIT']:
141 obj = bus.get_object(bus_name,obj_path)
142 intf = dbus.Interface(obj,init_intf)
143 print "Calling init method: " +obj_path+" : "+init_intf
144 intf.init()
145#
146 @dbus.service.method(DBUS_NAME,
147 in_signature='y', out_signature='ss')
148 def getObjFromIpmi(self,ipmi_id):
149 obj_path = ""
150 ## TODO: handle lookup failing
151 if (self.IPMI_ID_LOOKUP.has_key(ipmi_id) == True):
152 obj_info = self.IPMI_ID_LOOKUP[ipmi_id]
153 return obj_info
Norman James89de9162015-08-27 21:41:36 -0500154
155 @dbus.service.method(DBUS_NAME,
156 in_signature='s', out_signature='sis')
157 def gpioInit(self,name):
158 gpio_path = ''
159 gpio_num = 0
Norman James471ab592015-08-30 22:29:40 -0500160 if (System.GPIO_CONFIG.has_key(name) == False):
Norman James89de9162015-08-27 21:41:36 -0500161 # TODO: Error handling
162 print "ERROR: "+name+" not found in GPIO config table"
163 return ['',0,'']
164 else:
Norman James471ab592015-08-30 22:29:40 -0500165 gpio_num = System.GPIO_CONFIG[name]['gpio_num']
Norman James89de9162015-08-27 21:41:36 -0500166
Norman James471ab592015-08-30 22:29:40 -0500167 return [Openbmc.GPIO_DEV, gpio_num, System.GPIO_CONFIG[name]['direction']]
Norman James89de9162015-08-27 21:41:36 -0500168
169
170if __name__ == '__main__':
171 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
172 bus = dbus.SessionBus()
173 name = dbus.service.BusName(DBUS_NAME,bus)
174 obj = SystemManager(bus,OBJ_NAME)
Norman James5d78b4d2015-09-05 13:34:34 -0500175 mainloop = GObject.MainLoop()
Norman James89de9162015-08-27 21:41:36 -0500176
Norman James89de9162015-08-27 21:41:36 -0500177 print "Running SystemManager"
178 mainloop.run()
179