diff options
author | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2016-05-28 18:41:04 -0400 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2016-06-10 18:06:59 -0400 |
commit | 40a360c2a4feef97a8f7041e655b2a42e51e0224 (patch) | |
tree | 75dfea3064d7c3243788c72cb9f30e2ce6241dea /pysystemmgr | |
parent | a73122191a7aba80f97332687a2e03cfb0336981 (diff) | |
download | talos-skeleton-40a360c2a4feef97a8f7041e655b2a42e51e0224.tar.gz talos-skeleton-40a360c2a4feef97a8f7041e655b2a42e51e0224.zip |
Reorganize directory structure
Moving to directory per-application layout. This facilitates
building single applications which is useful in the Yocto build
environment since different applications satisfy different OpenBMC
build requirements.
A number of issues are also addressed:
- All applications were pulling in libsystemd and the gdbus libs
irrespective of whether or not they were needed.
- gpio.o duplicated in every application - moved to libopenbmc_intf
- Added install target
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Diffstat (limited to 'pysystemmgr')
l--------- | pysystemmgr/Makefile | 1 | ||||
l--------- | pysystemmgr/setup.cfg | 1 | ||||
-rw-r--r-- | pysystemmgr/setup.py | 6 | ||||
-rw-r--r-- | pysystemmgr/system_manager.py | 251 |
4 files changed, 259 insertions, 0 deletions
diff --git a/pysystemmgr/Makefile b/pysystemmgr/Makefile new file mode 120000 index 0000000..76a90fc --- /dev/null +++ b/pysystemmgr/Makefile @@ -0,0 +1 @@ +../Makefile.python
\ No newline at end of file diff --git a/pysystemmgr/setup.cfg b/pysystemmgr/setup.cfg new file mode 120000 index 0000000..29939b5 --- /dev/null +++ b/pysystemmgr/setup.cfg @@ -0,0 +1 @@ +../setup.cfg
\ No newline at end of file diff --git a/pysystemmgr/setup.py b/pysystemmgr/setup.py new file mode 100644 index 0000000..4207620 --- /dev/null +++ b/pysystemmgr/setup.py @@ -0,0 +1,6 @@ +from distutils.core import setup + +setup(name='pysystemmgr', + version='1.0', + scripts=['system_manager.py'], + ) diff --git a/pysystemmgr/system_manager.py b/pysystemmgr/system_manager.py new file mode 100644 index 0000000..754700b --- /dev/null +++ b/pysystemmgr/system_manager.py @@ -0,0 +1,251 @@ +#!/usr/bin/python -u + +import sys +import subprocess +import gobject +import dbus +import dbus.service +import dbus.mainloop.glib +import os +import time +import obmc.dbuslib.propertycacher as PropertyCacher +from obmc.dbuslib.bindings import DbusProperties, DbusObjectManager, get_dbus +import obmc.enums + +if (len(sys.argv) < 2): + print "Usage: system_manager.py [system name]" + exit(1) + +System = __import__(sys.argv[1]) + +DBUS_NAME = 'org.openbmc.managers.System' +OBJ_NAME = '/org/openbmc/managers/System' +HEARTBEAT_CHECK_INTERVAL = 20000 +STATE_START_TIMEOUT = 10 +INTF_SENSOR = 'org.openbmc.SensorValue' +INTF_ITEM = 'org.openbmc.InventoryItem' +INTF_CONTROL = 'org.openbmc.Control' + + +class SystemManager(DbusProperties,DbusObjectManager): + def __init__(self,bus,obj_name): + DbusProperties.__init__(self) + DbusObjectManager.__init__(self) + dbus.service.Object.__init__(self,bus,obj_name) + + bus.add_signal_receiver(self.NewObjectHandler, + signal_name = "InterfacesAdded", sender_keyword = 'bus_name') + bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState") + + self.Set(DBUS_NAME,"current_state","") + self.system_states = {} + self.bus_name_lookup = {} + self.bin_path = os.path.dirname(os.path.realpath(sys.argv[0])) + + for name in System.APPS.keys(): + sys_state = System.APPS[name]['system_state'] + if (self.system_states.has_key(sys_state) == False): + self.system_states[sys_state] = [] + self.system_states[sys_state].append(name) + + ## replace symbolic path in ID_LOOKUP + for category in System.ID_LOOKUP: + for key in System.ID_LOOKUP[category]: + val = System.ID_LOOKUP[category][key] + new_val = val.replace("<inventory_root>",System.INVENTORY_ROOT) + System.ID_LOOKUP[category][key] = new_val + + self.SystemStateHandler(System.SYSTEM_STATES[0]) + + if not os.path.exists(PropertyCacher.CACHE_PATH): + print "Creating cache directory: "+PropertyCacher.CACHE_PATH + os.makedirs(PropertyCacher.CACHE_PATH) + + self.InterfacesAdded(obj_name,self.properties) + print "SystemManager Init Done" + + + def SystemStateHandler(self,state_name): + ## clearing object started flags + current_state = self.Get(DBUS_NAME,"current_state") + try: + for obj_path in System.EXIT_STATE_DEPEND[current_state]: + System.EXIT_STATE_DEPEND[current_state][obj_path] = 0 + except: + pass + + print "Running System State: "+state_name + if (self.system_states.has_key(state_name)): + for name in self.system_states[state_name]: + self.start_process(name) + + if (state_name == "BMC_INIT"): + ## Add poll for heartbeat + gobject.timeout_add(HEARTBEAT_CHECK_INTERVAL, self.heartbeat_check) + + try: + cb = System.ENTER_STATE_CALLBACK[state_name] + for methd in cb.keys(): + obj = bus.get_object(cb[methd]['bus_name'],cb[methd]['obj_name'],introspect=False) + method = obj.get_dbus_method(methd,cb[methd]['interface_name']) + method() + except: + pass + + self.Set(DBUS_NAME,"current_state",state_name) + + def gotoNextState(self): + s = 0 + current_state = self.Get(DBUS_NAME,"current_state") + for i in range(len(System.SYSTEM_STATES)): + if (System.SYSTEM_STATES[i] == current_state): + s = i+1 + + if (s == len(System.SYSTEM_STATES)): + print "ERROR SystemManager: No more system states" + else: + new_state_name = System.SYSTEM_STATES[s] + print "SystemManager Goto System State: "+new_state_name + self.SystemStateHandler(new_state_name) + + + @dbus.service.method(DBUS_NAME, + in_signature='', out_signature='s') + def getSystemState(self): + return self.Get(DBUS_NAME,"current_state") + + def doObjectLookup(self,category,key): + bus_name = "" + obj_path = "" + intf_name = INTF_ITEM + try: + obj_path = System.ID_LOOKUP[category][key] + bus_name = self.bus_name_lookup[obj_path] + parts = obj_path.split('/') + if (parts[3] == 'sensors'): + intf_name = INTF_SENSOR + except Exception as e: + print "ERROR SystemManager: "+str(e)+" not found in lookup" + + return [bus_name,obj_path,intf_name] + + @dbus.service.method(DBUS_NAME, + in_signature='ss', out_signature='(sss)') + def getObjectFromId(self,category,key): + return self.doObjectLookup(category,key) + + @dbus.service.method(DBUS_NAME, + in_signature='sy', out_signature='(sss)') + def getObjectFromByteId(self,category,key): + byte = int(key) + return self.doObjectLookup(category,byte) + + # Get the FRU area names defined in ID_LOOKUP table given a fru_id. + # If serval areas are defined for a fru_id, the areas are returned + # together as a string with each area name seperated with ','. + # If no fru area defined in ID_LOOKUP, an empty string will be returned. + @dbus.service.method(DBUS_NAME, + in_signature='y', out_signature='s') + def getFRUArea(self,fru_id): + ret_str = '' + fru_id = '_' + str(fru_id) + area_list = [area for area in System.ID_LOOKUP['FRU_STR'].keys() \ + if area.endswith(fru_id)] + for area in area_list: + ret_str = area + ',' + ret_str + # remove the last ',' + return ret_str[:-1] + + def start_process(self,name): + if (System.APPS[name]['start_process'] == True): + app = System.APPS[name] + process_name = self.bin_path+"/"+app['process_name'] + cmdline = [ ] + cmdline.append(process_name) + if (app.has_key('args')): + for a in app['args']: + cmdline.append(a) + try: + print "Starting process: "+" ".join(cmdline)+": "+name + if (app['monitor_process'] == True): + app['popen'] = subprocess.Popen(cmdline) + else: + subprocess.Popen(cmdline) + + except Exception as e: + ## TODO: error + print "ERROR: starting process: "+" ".join(cmdline) + + def heartbeat_check(self): + for name in System.APPS.keys(): + app = System.APPS[name] + if (app['start_process'] == True and app.has_key('popen')): + ## make sure process is still alive + p = app['popen'] + p.poll() + if (p.returncode != None): + print "Process for "+name+" appears to be dead" + self.start_process(name) + + return True + + def NewObjectHandler(self, obj_path, iprops, bus_name = None): + current_state = self.Get(DBUS_NAME,"current_state") + if (self.bus_name_lookup.has_key(obj_path)): + if (self.bus_name_lookup[obj_path] == bus_name): + return + self.bus_name_lookup[obj_path] = bus_name + print "New object: "+obj_path+" ("+bus_name+")" + try: + if (System.EXIT_STATE_DEPEND[current_state].has_key(obj_path) == True): + System.EXIT_STATE_DEPEND[current_state][obj_path] = 1 + ## check if all required objects are started to move to next state + state = 1 + for obj_path in System.EXIT_STATE_DEPEND[current_state]: + if (System.EXIT_STATE_DEPEND[current_state][obj_path] == 0): + state = 0 + ## all required objects have started so go to next state + if (state == 1): + print "All required objects started for "+current_state + self.gotoNextState() + except: + pass + + + @dbus.service.method(DBUS_NAME, + in_signature='s', out_signature='sis') + def gpioInit(self,name): + gpio_path = '' + gpio_num = -1 + r = ['',gpio_num,''] + if (System.GPIO_CONFIG.has_key(name) == False): + # TODO: Error handling + print "ERROR: "+name+" not found in GPIO config table" + else: + + gpio_num = -1 + gpio = System.GPIO_CONFIG[name] + if (System.GPIO_CONFIG[name].has_key('gpio_num')): + gpio_num = gpio['gpio_num'] + else: + if (System.GPIO_CONFIG[name].has_key('gpio_pin')): + gpio_num = System.convertGpio(gpio['gpio_pin']) + else: + print "ERROR: SystemManager - GPIO lookup failed for "+name + + if (gpio_num != -1): + r = [obmc.enums.GPIO_DEV, gpio_num, gpio['direction']] + return r + + + +if __name__ == '__main__': + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + bus = get_dbus() + name = dbus.service.BusName(DBUS_NAME,bus) + obj = SystemManager(bus,OBJ_NAME) + mainloop = gobject.MainLoop() + + print "Running SystemManager" + mainloop.run() + |