blob: 108f81c7121c2b167cf86418038db5d76eebd608 [file] [log] [blame]
Norman James9d0f65f2015-10-26 17:13:13 -05001#!/usr/bin/python -u
2
3import sys
4#from gi.repository import GObject
5import gobject
6import dbus
7import dbus.service
8import dbus.mainloop.glib
9import cPickle
10import glob
11import os
12
13if (len(sys.argv) < 2):
14 print "Usage: property_manager.py [system name]"
15 exit(1)
16System = __import__(sys.argv[1])
17import Openbmc
18
19DBUS_NAME = 'org.openbmc.managers.Property'
20OBJ_NAME = '/org/openbmc/managers/Property'
21INTF_NAME = 'org.openbmc.managers.Property'
22
23class PropertyManager(dbus.service.Object):
24 def __init__(self,bus,name):
25 dbus.service.Object.__init__(self,bus,name)
26 if not os.path.exists(System.CACHE_PATH):
27 os.makedirs(System.CACHE_PATH)
28
29
30 bus.add_signal_receiver(self.PropertyChangedHandler,
31 dbus_interface = 'org.freedesktop.DBus.Properties',
32 signal_name = 'PropertiesChanged', sender_keyword='bus_name', path_keyword='path')
33
34 bus.add_signal_receiver(self.RegisterPersistantInterface,
35 dbus_interface = 'org.openbmc.PersistantInterface',
36 signal_name = 'Register', sender_keyword='bus_name', path_keyword='path')
37
38 self.registered_interfaces = {}
39
40
41 def RegisterPersistantInterface(self,interface_name, bus_name = None, path = None):
42 interface_name = str(interface_name)
43 print "Registering cached object (interface): "+path+" ("+interface_name+")"
44 self.registered_interfaces[interface_name] = True
45 self.loadFromCache(bus_name,path,interface_name)
46
47
48 def PropertyChangedHandler(self, interface_name, changed_properties,
49 invalidated_properties, bus_name = None, path = None):
50 ## TODO: just save all properties, probably should journal changes instead
51 if (self.registered_interfaces.has_key(interface_name)):
52 self.saveToCache(bus_name,path,interface_name)
53
54 def getCacheFilename(self,obj_path,intf_name):
55 name = obj_path.replace('/','.')
56 filename = System.CACHE_PATH+name[1:]+"@"+intf_name+".props"
57 return filename
58
Norman James9d0f65f2015-10-26 17:13:13 -050059 def saveToCache(self, bus_name, object_path, interface_name):
60 print "Caching: "+object_path
61 try:
62 obj = bus.get_object(bus_name,object_path)
63 intf = dbus.Interface(obj,"org.freedesktop.DBus.Properties")
64 props = intf.GetAll(interface_name)
65 output = open(self.getCacheFilename(object_path,interface_name), 'wb')
66 ## save properties
67 dbus_props = {}
68 for p in props.keys():
69 dbus_prop = Openbmc.DbusVariable(p,props[p])
70 dbus_props[str(p)] = dbus_prop.getBaseValue()
71 cPickle.dump(dbus_props,output)
72 except Exception as e:
73 print "ERROR: "+str(e)
74 finally:
75 output.close()
76
77 def loadFromCache(self,bus_name, object_path, interface_name):
78 ## overlay with pickled data
79 filename=self.getCacheFilename(object_path,interface_name)
80 if (os.path.isfile(filename)):
81 print "Loading from cache: "+filename
82 try:
83 p = open(filename, 'rb')
84 data = cPickle.load(p)
85 obj = bus.get_object(bus_name,object_path)
86 ## TODO: don't use exception to determine whether interface is implemented
87 try:
88 intf = dbus.Interface(obj,"org.openbmc.Object.Properties")
89 props = intf.SetMultiple(interface_name,data)
90 except TypeError as t:
91 print "SetMultiple interface doesn't exist, doing 1 set a time"
92 intf = dbus.Interface(obj,dbus.PROPERTIES_IFACE)
93 for prop in data:
94 intf.Set(interface_name,prop,data[prop])
95
96
97 except Exception as e:
98 print "ERROR: Loading cache file: " +str(e)
99 finally:
100 p.close()
101
102
103if __name__ == '__main__':
104 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
105 bus = Openbmc.getDBus()
106 name = dbus.service.BusName(DBUS_NAME,bus)
107 obj = PropertyManager(bus,OBJ_NAME)
108 mainloop = gobject.MainLoop()
109
110 print "Running Property Manager"
111 mainloop.run()
112