blob: cb37c41e0eecc8f67a1f66e0e4f552de59ed99e9 [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 James90baede2015-09-02 20:32:49 -050035 bus.add_signal_receiver(self.CacheMeHandler,
36 signal_name = 'CacheMe', path_keyword='path',interface_keyword='interface')
Norman James9e6acf92015-09-08 07:00:04 -050037 bus.add_signal_receiver(self.HeartbeatHandler, signal_name = "Heartbeat")
Norman James90baede2015-09-02 20:32:49 -050038
39 try:
40 # launch dbus object processes
41 for bus_name in System.SYSTEM_CONFIG.keys():
42 self.start_process(bus_name)
43 except Exception as e:
44 ## TODO: error handling
45 pass
46
Norman James9e6acf92015-09-08 07:00:04 -050047 ## Add poll for heartbeat
Norman James5d78b4d2015-09-05 13:34:34 -050048 GObject.timeout_add(HEARTBEAT_CHECK_INTERVAL, self.heartbeat_check)
Norman James9e6acf92015-09-08 07:00:04 -050049
Norman James471ab592015-08-30 22:29:40 -050050
Norman James90baede2015-09-02 20:32:49 -050051 def CacheMeHandler(self,busname,path=None,interface=None):
52 #interface_name = 'org.openbmc.Fru'
53 print "CacheME: "+busname+","+path+","+interface
54 data = {}
55 cache = System.CACHED_INTERFACES.has_key(interface)
Norman James5d78b4d2015-09-05 13:34:34 -050056 self.property_manager.saveProperties(busname,path,interface,cache,data)
Norman James90baede2015-09-02 20:32:49 -050057
58
Norman James471ab592015-08-30 22:29:40 -050059 def start_process(self,bus_name):
Norman James5d78b4d2015-09-05 13:34:34 -050060 if (System.SYSTEM_CONFIG[bus_name]['start_process'] == True):
61 process_name = System.BIN_PATH+System.SYSTEM_CONFIG[bus_name]['process_name']
62 cmdline = [ ]
63 cmdline.append(process_name)
64 for instance in System.SYSTEM_CONFIG[bus_name]['instances']:
65 cmdline.append(instance['name'])
66 try:
67 print "Starting process: "+" ".join(cmdline)
68 System.SYSTEM_CONFIG[bus_name]['popen'] = subprocess.Popen(cmdline);
69 except Exception as e:
70 ## TODO: error
71 print "Error starting process: "+" ".join(cmdline)
Norman James471ab592015-08-30 22:29:40 -050072
Norman James89de9162015-08-27 21:41:36 -050073 def heartbeat_check(self):
74 print "heartbeat check"
Norman James471ab592015-08-30 22:29:40 -050075 for bus_name in System.SYSTEM_CONFIG.keys():
Norman James5d78b4d2015-09-05 13:34:34 -050076 if (System.SYSTEM_CONFIG[bus_name]['start_process'] == True):
77 ## even if process doesn't request heartbeat check,
78 ## make sure process is still alive
79 p = System.SYSTEM_CONFIG[bus_name]['popen']
80 p.poll()
81 if (p.returncode != None):
82 print "Process for "+bus_name+" appears to be dead"
83 self.start_process(bus_name)
84
85 ## process is alive, now check if heartbeat received
86 ## during previous interval
87 elif (System.SYSTEM_CONFIG[bus_name]['heartbeat'] == 'yes'):
88 if (System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] == 0):
89 print "Heartbeat error: "+bus_name
90 p = System.SYSTEM_CONFIG[bus_name]['popen']
91 ## TODO: error checking
92 p.poll()
93 if (p.returncode == None):
94 print "Process must be hung, so killing"
95 p.kill()
Norman James471ab592015-08-30 22:29:40 -050096
Norman James5d78b4d2015-09-05 13:34:34 -050097 self.start_process(bus_name)
98 else:
99 System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] = 0
100 print "Heartbeat ok: "+bus_name
Norman James471ab592015-08-30 22:29:40 -0500101
102 return True
Norman James89de9162015-08-27 21:41:36 -0500103
Norman James90baede2015-09-02 20:32:49 -0500104 def HeartbeatHandler(self,bus_name):
Norman James471ab592015-08-30 22:29:40 -0500105 System.SYSTEM_CONFIG[bus_name]['heartbeat_count']=1
Norman James89de9162015-08-27 21:41:36 -0500106
Norman James90baede2015-09-02 20:32:49 -0500107 def NewBusHandler(self, bus_name, a, b):
Norman James471ab592015-08-30 22:29:40 -0500108 if (len(b) > 0 and bus_name.find(Openbmc.BUS_PREFIX) == 0):
109 if (System.SYSTEM_CONFIG.has_key(bus_name)):
110 System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] = 0
Norman James90baede2015-09-02 20:32:49 -0500111 obj_root = "/"+bus_name.replace('.','/')
112 obj_paths = []
113
114 ## Loads object properties from system config file
115 ## then overlays saved properties from file
116 for instance in System.SYSTEM_CONFIG[bus_name]['instances']:
117 obj_path = obj_root+'/'+instance['name']
118 obj_paths.append(obj_path)
119 if (instance.has_key('properties')):
Norman James9e6acf92015-09-08 07:00:04 -0500120 print "load props: "+obj_path
Norman James5d78b4d2015-09-05 13:34:34 -0500121 self.property_manager.loadProperties(bus_name,obj_path, instance['properties'])
Norman James90baede2015-09-02 20:32:49 -0500122
Norman James9e6acf92015-09-08 07:00:04 -0500123 ## scan all used interfaces and get interfaces with init method
124
125
Norman James90baede2015-09-02 20:32:49 -0500126 ## After object properties are setup, call init method if requested
Norman James9e6acf92015-09-08 07:00:04 -0500127 #if (System.SYSTEM_CONFIG[bus_name].has_key('init_methods')):
128 for obj_path in obj_paths:
129 obj = bus.get_object(bus_name,obj_path)
130 methods = Openbmc.get_methods(obj)
131 for intf_name in methods.keys():
132 if (methods[intf_name].has_key('init')):
133 intf = dbus.Interface(obj,intf_name)
134 print "Calling init: " +intf_name
Norman James90baede2015-09-02 20:32:49 -0500135 intf.init()
Norman James89de9162015-08-27 21:41:36 -0500136
Norman James89de9162015-08-27 21:41:36 -0500137
Norman James89de9162015-08-27 21:41:36 -0500138
139 @dbus.service.method(DBUS_NAME,
140 in_signature='s', out_signature='sis')
141 def gpioInit(self,name):
142 gpio_path = ''
143 gpio_num = 0
Norman James471ab592015-08-30 22:29:40 -0500144 if (System.GPIO_CONFIG.has_key(name) == False):
Norman James89de9162015-08-27 21:41:36 -0500145 # TODO: Error handling
146 print "ERROR: "+name+" not found in GPIO config table"
147 return ['',0,'']
148 else:
Norman James471ab592015-08-30 22:29:40 -0500149 gpio_num = System.GPIO_CONFIG[name]['gpio_num']
Norman James89de9162015-08-27 21:41:36 -0500150
Norman James471ab592015-08-30 22:29:40 -0500151 return [Openbmc.GPIO_DEV, gpio_num, System.GPIO_CONFIG[name]['direction']]
Norman James89de9162015-08-27 21:41:36 -0500152
153
154if __name__ == '__main__':
155 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
156 bus = dbus.SessionBus()
157 name = dbus.service.BusName(DBUS_NAME,bus)
158 obj = SystemManager(bus,OBJ_NAME)
Norman James5d78b4d2015-09-05 13:34:34 -0500159 mainloop = GObject.MainLoop()
Norman James89de9162015-08-27 21:41:36 -0500160
Norman James89de9162015-08-27 21:41:36 -0500161 print "Running SystemManager"
162 mainloop.run()
163