blob: e96e547e0d8a584e2c3b4b2557e63ee86010c488 [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
6
Norman James89de9162015-08-27 21:41:36 -05007import dbus
8import dbus.service
9import dbus.mainloop.glib
Norman James90baede2015-09-02 20:32:49 -050010import os
11import PropertyManager
Norman James471ab592015-08-30 22:29:40 -050012
13if (len(sys.argv) < 2):
14 print "Usage: system_manager.py [system name]"
15 exit(1)
16
17System = __import__(sys.argv[1])
18import Openbmc
Norman James89de9162015-08-27 21:41:36 -050019
20DBUS_NAME = 'org.openbmc.managers.System'
21OBJ_NAME = '/org/openbmc/managers/System'
Norman James471ab592015-08-30 22:29:40 -050022HEARTBEAT_CHECK_INTERVAL = 20000
Norman James89de9162015-08-27 21:41:36 -050023
Norman James89de9162015-08-27 21:41:36 -050024
25class SystemManager(dbus.service.Object):
26 def __init__(self,bus,name):
27 dbus.service.Object.__init__(self,bus,name)
Norman James90baede2015-09-02 20:32:49 -050028
Norman James5d78b4d2015-09-05 13:34:34 -050029 self.property_manager = PropertyManager.PropertyManager(bus,System.CACHE_PATH)
Norman James90baede2015-09-02 20:32:49 -050030 ## Signal handlers
31 bus.add_signal_receiver(self.NewBusHandler,
Norman James89de9162015-08-27 21:41:36 -050032 dbus_interface = 'org.freedesktop.DBus',
33 signal_name = "NameOwnerChanged")
Norman James90baede2015-09-02 20:32:49 -050034 bus.add_signal_receiver(self.CacheMeHandler,
35 signal_name = 'CacheMe', path_keyword='path',interface_keyword='interface')
Norman James89de9162015-08-27 21:41:36 -050036
Norman James90baede2015-09-02 20:32:49 -050037
38 try:
39 # launch dbus object processes
40 for bus_name in System.SYSTEM_CONFIG.keys():
41 self.start_process(bus_name)
42 except Exception as e:
43 ## TODO: error handling
44 pass
45
46 bus.add_signal_receiver(self.HeartbeatHandler, signal_name = "Heartbeat")
Norman James5d78b4d2015-09-05 13:34:34 -050047 GObject.timeout_add(HEARTBEAT_CHECK_INTERVAL, self.heartbeat_check)
Norman James471ab592015-08-30 22:29:40 -050048
Norman James90baede2015-09-02 20:32:49 -050049 def CacheMeHandler(self,busname,path=None,interface=None):
50 #interface_name = 'org.openbmc.Fru'
51 print "CacheME: "+busname+","+path+","+interface
52 data = {}
53 cache = System.CACHED_INTERFACES.has_key(interface)
Norman James5d78b4d2015-09-05 13:34:34 -050054 self.property_manager.saveProperties(busname,path,interface,cache,data)
Norman James90baede2015-09-02 20:32:49 -050055
56
Norman James471ab592015-08-30 22:29:40 -050057 def start_process(self,bus_name):
Norman James5d78b4d2015-09-05 13:34:34 -050058 if (System.SYSTEM_CONFIG[bus_name]['start_process'] == True):
59 process_name = System.BIN_PATH+System.SYSTEM_CONFIG[bus_name]['process_name']
60 cmdline = [ ]
61 cmdline.append(process_name)
62 for instance in System.SYSTEM_CONFIG[bus_name]['instances']:
63 cmdline.append(instance['name'])
64 try:
65 print "Starting process: "+" ".join(cmdline)
66 System.SYSTEM_CONFIG[bus_name]['popen'] = subprocess.Popen(cmdline);
67 except Exception as e:
68 ## TODO: error
69 print "Error starting process: "+" ".join(cmdline)
Norman James471ab592015-08-30 22:29:40 -050070
Norman James89de9162015-08-27 21:41:36 -050071 def heartbeat_check(self):
72 print "heartbeat check"
Norman James471ab592015-08-30 22:29:40 -050073 for bus_name in System.SYSTEM_CONFIG.keys():
Norman James5d78b4d2015-09-05 13:34:34 -050074 if (System.SYSTEM_CONFIG[bus_name]['start_process'] == True):
75 ## even if process doesn't request heartbeat check,
76 ## make sure process is still alive
77 p = System.SYSTEM_CONFIG[bus_name]['popen']
78 p.poll()
79 if (p.returncode != None):
80 print "Process for "+bus_name+" appears to be dead"
81 self.start_process(bus_name)
82
83 ## process is alive, now check if heartbeat received
84 ## during previous interval
85 elif (System.SYSTEM_CONFIG[bus_name]['heartbeat'] == 'yes'):
86 if (System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] == 0):
87 print "Heartbeat error: "+bus_name
88 p = System.SYSTEM_CONFIG[bus_name]['popen']
89 ## TODO: error checking
90 p.poll()
91 if (p.returncode == None):
92 print "Process must be hung, so killing"
93 p.kill()
Norman James471ab592015-08-30 22:29:40 -050094
Norman James5d78b4d2015-09-05 13:34:34 -050095 self.start_process(bus_name)
96 else:
97 System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] = 0
98 print "Heartbeat ok: "+bus_name
Norman James471ab592015-08-30 22:29:40 -050099
100 return True
Norman James89de9162015-08-27 21:41:36 -0500101
Norman James90baede2015-09-02 20:32:49 -0500102 def HeartbeatHandler(self,bus_name):
Norman James471ab592015-08-30 22:29:40 -0500103 System.SYSTEM_CONFIG[bus_name]['heartbeat_count']=1
Norman James89de9162015-08-27 21:41:36 -0500104
Norman James90baede2015-09-02 20:32:49 -0500105 def NewBusHandler(self, bus_name, a, b):
Norman James471ab592015-08-30 22:29:40 -0500106 if (len(b) > 0 and bus_name.find(Openbmc.BUS_PREFIX) == 0):
107 if (System.SYSTEM_CONFIG.has_key(bus_name)):
108 System.SYSTEM_CONFIG[bus_name]['heartbeat_count'] = 0
Norman James90baede2015-09-02 20:32:49 -0500109 obj_root = "/"+bus_name.replace('.','/')
110 obj_paths = []
111
112 ## Loads object properties from system config file
113 ## then overlays saved properties from file
114 for instance in System.SYSTEM_CONFIG[bus_name]['instances']:
115 obj_path = obj_root+'/'+instance['name']
116 obj_paths.append(obj_path)
117 if (instance.has_key('properties')):
Norman James5d78b4d2015-09-05 13:34:34 -0500118 self.property_manager.loadProperties(bus_name,obj_path, instance['properties'])
Norman James90baede2015-09-02 20:32:49 -0500119
120 ## After object properties are setup, call init method if requested
121 if (System.SYSTEM_CONFIG[bus_name].has_key('init_methods')):
122 for obj_path in obj_paths:
123 for init_interface in System.SYSTEM_CONFIG[bus_name]['init_methods']:
124 obj = bus.get_object(bus_name,obj_path)
125 intf = dbus.Interface(obj,init_interface)
126 print "calling init:" +init_interface
127 intf.init()
Norman James89de9162015-08-27 21:41:36 -0500128
Norman James89de9162015-08-27 21:41:36 -0500129
Norman James89de9162015-08-27 21:41:36 -0500130
131 @dbus.service.method(DBUS_NAME,
132 in_signature='s', out_signature='sis')
133 def gpioInit(self,name):
134 gpio_path = ''
135 gpio_num = 0
Norman James471ab592015-08-30 22:29:40 -0500136 if (System.GPIO_CONFIG.has_key(name) == False):
Norman James89de9162015-08-27 21:41:36 -0500137 # TODO: Error handling
138 print "ERROR: "+name+" not found in GPIO config table"
139 return ['',0,'']
140 else:
Norman James471ab592015-08-30 22:29:40 -0500141 gpio_num = System.GPIO_CONFIG[name]['gpio_num']
Norman James89de9162015-08-27 21:41:36 -0500142
Norman James471ab592015-08-30 22:29:40 -0500143 return [Openbmc.GPIO_DEV, gpio_num, System.GPIO_CONFIG[name]['direction']]
Norman James89de9162015-08-27 21:41:36 -0500144
145
146if __name__ == '__main__':
147 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
148 bus = dbus.SessionBus()
149 name = dbus.service.BusName(DBUS_NAME,bus)
150 obj = SystemManager(bus,OBJ_NAME)
Norman James5d78b4d2015-09-05 13:34:34 -0500151 mainloop = GObject.MainLoop()
Norman James89de9162015-08-27 21:41:36 -0500152
Norman James89de9162015-08-27 21:41:36 -0500153 print "Running SystemManager"
154 mainloop.run()
155