blob: 7b902c232af41e8a8bd9396ce640c9874209d543 [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
5import gobject
6import dbus
7import dbus.service
8import dbus.mainloop.glib
9import xml.etree.ElementTree as ET
Norman James471ab592015-08-30 22:29:40 -050010
11if (len(sys.argv) < 2):
12 print "Usage: system_manager.py [system name]"
13 exit(1)
14
15System = __import__(sys.argv[1])
16import Openbmc
Norman James89de9162015-08-27 21:41:36 -050017
18DBUS_NAME = 'org.openbmc.managers.System'
19OBJ_NAME = '/org/openbmc/managers/System'
Norman James471ab592015-08-30 22:29:40 -050020HEARTBEAT_CHECK_INTERVAL = 20000
Norman James89de9162015-08-27 21:41:36 -050021
22def findConfigInstance(bus_name,obj_path):
23 line = obj_path.split('/')
24 instance_name = line[len(line)-1]
Norman James471ab592015-08-30 22:29:40 -050025 if (System.SYSTEM_CONFIG.has_key(bus_name) == False):
Norman James89de9162015-08-27 21:41:36 -050026 return {}
Norman James471ab592015-08-30 22:29:40 -050027 for instance in System.SYSTEM_CONFIG[bus_name]['instances']:
Norman James89de9162015-08-27 21:41:36 -050028 if (instance['name'] == instance_name):
29 return instance
30
Norman James471ab592015-08-30 22:29:40 -050031def parseIntrospection(bus_name,obj_name,interfaces,init_interfaces):
Norman James89de9162015-08-27 21:41:36 -050032 obj = bus.get_object(bus_name, obj_name)
33 introspect_iface = dbus.Interface(obj,'org.freedesktop.DBus.Introspectable')
34 tree = ET.ElementTree(ET.fromstring(introspect_iface.Introspect()))
35 root = tree.getroot()
36 interfaces[obj_name] = []
Norman James471ab592015-08-30 22:29:40 -050037 init_interfaces[obj_name] = {}
Norman James89de9162015-08-27 21:41:36 -050038 for intf in root.iter('interface'):
39 intf_name = intf.attrib['name']
40 if (intf_name == 'org.freedesktop.DBus.ObjectManager'):
41 manager = dbus.Interface(obj,'org.freedesktop.DBus.ObjectManager')
42 for managed_obj in manager.GetManagedObjects():
Norman James471ab592015-08-30 22:29:40 -050043 parseIntrospection(bus_name,managed_obj,interfaces,init_interfaces)
44 elif (intf_name.find(Openbmc.BUS_PREFIX) == 0):
Norman James89de9162015-08-27 21:41:36 -050045 interfaces[obj_name].append(intf_name)
Norman James471ab592015-08-30 22:29:40 -050046 for method in intf.iter('method'):
47 if (method.attrib['name'] == 'init'):
48 #print "Init: "+obj_name+" : "+intf_name
49 init_interfaces[obj_name][intf_name]=1
50
51
Norman James89de9162015-08-27 21:41:36 -050052
53
54class SystemManager(dbus.service.Object):
55 def __init__(self,bus,name):
56 dbus.service.Object.__init__(self,bus,name)
57 bus.add_signal_receiver(self.request_name,
58 dbus_interface = 'org.freedesktop.DBus',
59 signal_name = "NameOwnerChanged")
60 # launch dbus object processes
Norman James471ab592015-08-30 22:29:40 -050061 for bus_name in System.SYSTEM_CONFIG.keys():
62 self.start_process(bus_name)
Norman James89de9162015-08-27 21:41:36 -050063
Norman James471ab592015-08-30 22:29:40 -050064 gobject.timeout_add(HEARTBEAT_CHECK_INTERVAL, self.heartbeat_check)
65
66 def start_process(self,bus_name):
67 exe_name = System.SYSTEM_CONFIG[bus_name]['exe_name']
68 cmdline = [ ]
69 cmdline.append(exe_name)
70 for instance in System.SYSTEM_CONFIG[bus_name]['instances']:
71 cmdline.append(instance['name'])
72 try:
73 print "Starting process: "+" ".join(cmdline)
74 System.SYSTEM_CONFIG[bus_name]['popen'] = subprocess.Popen(cmdline);
75 except Exception as e:
76 ## TODO: error
77 print "Error starting process: "+" ".join(cmdline)
78
Norman James89de9162015-08-27 21:41:36 -050079
80 def heartbeat_check(self):
81 print "heartbeat check"
Norman James471ab592015-08-30 22:29:40 -050082 for bus_name in System.SYSTEM_CONFIG.keys():
83 ## even if process doesn't request heartbeat check,
84 ## make sure process is still alive
85 p = System.SYSTEM_CONFIG[bus_name]['popen']
86 p.poll()
87 if (p.returncode != None):
88 print "Process for "+bus_name+" appears to be dead"
89 self.start_process(bus_name)
90
91 elif (System.SYSTEM_CONFIG[bus_name]['heartbeat'] == 'yes'):
92 if (System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] == 0):
Norman James89de9162015-08-27 21:41:36 -050093 print "Heartbeat error: "+bus_name
Norman James471ab592015-08-30 22:29:40 -050094 p = System.SYSTEM_CONFIG[bus_name]['popen']
95 p.poll()
96 if (p.returncode == None):
97 print "Process must be hung, so killing"
98 p.kill()
99
100 self.start_process(bus_name)
Norman James89de9162015-08-27 21:41:36 -0500101 else:
Norman James471ab592015-08-30 22:29:40 -0500102 System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] = 0
103 print "Heartbeat ok: "+bus_name
104
105 return True
Norman James89de9162015-08-27 21:41:36 -0500106
107 def heartbeat_update(self,bus_name):
Norman James471ab592015-08-30 22:29:40 -0500108 System.SYSTEM_CONFIG[bus_name]['heartbeat_count']=1
Norman James89de9162015-08-27 21:41:36 -0500109
110 def setup_sensor(self,intf):
111 pass
112
113 def request_name(self, bus_name, a, b):
Norman James471ab592015-08-30 22:29:40 -0500114 if (len(b) > 0 and bus_name.find(Openbmc.BUS_PREFIX) == 0):
115 if (System.SYSTEM_CONFIG.has_key(bus_name)):
116 System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] = 0
117 obj_name = "/"+bus_name.replace('.','/')
118 interfaces = {}
119 init_interfaces = {}
120 # introspect object to get used interfaces
121 parseIntrospection(bus_name,obj_name,interfaces,init_interfaces)
122 for obj_path in interfaces.keys():
123 # find instance in system config
124 instance = findConfigInstance(bus_name,obj_path)
125 for intf_name in interfaces[obj_path]:
126 self.initObject(bus_name,obj_path,intf_name,instance)
127 for init_intf in init_interfaces[obj_path].keys():
128 obj = bus.get_object(bus_name,obj_path)
129 intf = dbus.Interface(obj,init_intf)
130 intf.init()
Norman James89de9162015-08-27 21:41:36 -0500131
Norman James89de9162015-08-27 21:41:36 -0500132
Norman James471ab592015-08-30 22:29:40 -0500133 def initObject(self,bus_name,obj_path,intf_name,instance):
134 obj = bus.get_object(bus_name,obj_path)
135 intf = dbus.Interface(obj,intf_name)
136 if (instance.has_key('properties')):
137 properties = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
138 for prop_intf in instance['properties']:
139 for prop in instance['properties'][prop_intf]:
140 value = instance['properties'][prop_intf][prop]
141 properties.Set(prop_intf,prop,value)
Norman James89de9162015-08-27 21:41:36 -0500142
Norman James471ab592015-08-30 22:29:40 -0500143 ## TODO: fix this explicit check
144 if (intf_name == 'org.openbmc.Control' or intf_name == 'org.openbmc.SensorInteger'):
145 if (System.SYSTEM_CONFIG[bus_name]['heartbeat'] == 'yes'):
146 print "Add heartbeat: "+intf_name;
147 bus.add_signal_receiver(self.heartbeat_update,
148 dbus_interface = intf_name,
149 signal_name = "Heartbeat")
150
151 if (instance.has_key('parameters')):
152 intf.setConfigData(instance['parameters'])
153
Norman James89de9162015-08-27 21:41:36 -0500154
155 @dbus.service.signal(DBUS_NAME)
156 def CriticalThreshold(self, obj):
157 print "Critical: "+obj
158
159 @dbus.service.signal(DBUS_NAME)
160 def WarningThreshold(self, obj):
161 print "Warning: "+obj
162
163 @dbus.service.method(DBUS_NAME,
164 in_signature='s', out_signature='sis')
165 def gpioInit(self,name):
166 gpio_path = ''
167 gpio_num = 0
Norman James471ab592015-08-30 22:29:40 -0500168 if (System.GPIO_CONFIG.has_key(name) == False):
Norman James89de9162015-08-27 21:41:36 -0500169 # TODO: Error handling
170 print "ERROR: "+name+" not found in GPIO config table"
171 return ['',0,'']
172 else:
Norman James471ab592015-08-30 22:29:40 -0500173 gpio_num = System.GPIO_CONFIG[name]['gpio_num']
Norman James89de9162015-08-27 21:41:36 -0500174
Norman James471ab592015-08-30 22:29:40 -0500175 return [Openbmc.GPIO_DEV, gpio_num, System.GPIO_CONFIG[name]['direction']]
Norman James89de9162015-08-27 21:41:36 -0500176
177
178if __name__ == '__main__':
179 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
180 bus = dbus.SessionBus()
181 name = dbus.service.BusName(DBUS_NAME,bus)
182 obj = SystemManager(bus,OBJ_NAME)
183 mainloop = gobject.MainLoop()
184
Norman James89de9162015-08-27 21:41:36 -0500185 print "Running SystemManager"
186 mainloop.run()
187