summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Jeffery <andrew@aj.id.au>2018-05-16 13:53:30 +0930
committerAndrew Jeffery <andrew@aj.id.au>2018-05-16 14:57:29 +0930
commitce2a6f0354ed450ada2171e239ac1056b3df3126 (patch)
treee6b3a4b49aaa62828a49cd5b04d39e3ea673b084
parent13d0dc9fcb9e8003e6f58b8eda79b8901709bed2 (diff)
downloadpyphosphor-ce2a6f0354ed450ada2171e239ac1056b3df3126.tar.gz
pyphosphor-ce2a6f0354ed450ada2171e239ac1056b3df3126.zip
pathtree: Allow get() on subtrees
When running recent PathTree modifications on a BMC we can see failures in the log such as "Failed to invoke ObjectMapper method" from the phosphor-fru-fault-monitor. This can be triggered via the openbmc-test-automation suite, for example with the following command $ robot -v OPENBMC_HOST:w5.aus.stglabs.ibm.com --include \ Create_Test_Error_Callout_And_Verify extended/test_association.robot Capturing the DBus traffic across this test case (`busctl capture > dbus.pcap`) and analysing it with Wireshark showed the following method invocation: ``` 0000 6c 01 00 01 53 00 00 00 16 00 00 00 c6 00 00 00 l...S........... 0010 01 01 6f 00 22 00 00 00 2f 78 79 7a 2f 6f 70 65 ..o.".../xyz/ope 0020 6e 62 6d 63 5f 70 72 6f 6a 65 63 74 2f 6f 62 6a nbmc_project/obj 0030 65 63 74 5f 6d 61 70 70 65 72 00 00 00 00 00 00 ect_mapper...... 0040 03 01 73 00 09 00 00 00 47 65 74 4f 62 6a 65 63 ..s.....GetObjec 0050 74 00 00 00 00 00 00 00 02 01 73 00 20 00 00 00 t.........s. ... 0060 78 79 7a 2e 6f 70 65 6e 62 6d 63 5f 70 72 6f 6a xyz.openbmc_proj 0070 65 63 74 2e 4f 62 6a 65 63 74 4d 61 70 70 65 72 ect.ObjectMapper 0080 00 00 00 00 00 00 00 00 06 01 73 00 20 00 00 00 ..........s. ... 0090 78 79 7a 2e 6f 70 65 6e 62 6d 63 5f 70 72 6f 6a xyz.openbmc_proj 00a0 65 63 74 2e 4f 62 6a 65 63 74 4d 61 70 70 65 72 ect.ObjectMapper 00b0 00 00 00 00 00 00 00 00 08 01 67 00 03 73 61 73 ..........g..sas 00c0 00 00 00 00 00 00 00 00 07 01 73 00 05 00 00 00 ..........s..... 00d0 3a 31 2e 35 37 00 00 00 20 00 00 00 2f 78 79 7a :1.57... .../xyz 00e0 2f 6f 70 65 6e 62 6d 63 5f 70 72 6f 6a 65 63 74 /openbmc_project 00f0 2f 6c 65 64 2f 67 72 6f 75 70 73 2f 00 00 00 00 /led/groups/.... 0100 27 00 00 00 22 00 00 00 6f 72 67 2e 66 72 65 65 '..."...org.free 0110 64 65 73 6b 74 6f 70 2e 44 42 75 73 2e 4f 62 6a desktop.DBus.Obj 0120 65 63 74 4d 61 6e 61 67 65 72 00 ectManager. ``` and the response ``` 0000 6c 03 01 01 3f 00 00 00 9d 08 00 00 5e 00 00 00 l...?.......^... 0010 06 01 73 00 05 00 00 00 3a 31 2e 35 37 00 00 00 ..s.....:1.57... 0020 04 01 73 00 27 00 00 00 6f 72 67 2e 66 72 65 65 ..s.'...org.free 0030 64 65 73 6b 74 6f 70 2e 44 42 75 73 2e 45 72 72 desktop.DBus.Err 0040 6f 72 2e 46 69 6c 65 4e 6f 74 46 6f 75 6e 64 00 or.FileNotFound. 0050 05 01 75 00 16 00 00 00 08 01 67 00 01 73 00 00 ..u.......g..s.. 0060 07 01 73 00 05 00 00 00 3a 31 2e 31 35 00 00 00 ..s.....:1.15... 0070 3a 00 00 00 70 61 74 68 20 6f 72 20 6f 62 6a 65 :...path or obje 0080 63 74 20 6e 6f 74 20 66 6f 75 6e 64 3a 20 2f 78 ct not found: /x 0090 79 7a 2f 6f 70 65 6e 62 6d 63 5f 70 72 6f 6a 65 yz/openbmc_proje 00a0 63 74 2f 6c 65 64 2f 67 72 6f 75 70 73 2f 00 ct/led/groups/. ``` These packets translate to the following `busctl` invocation and response: ``` root@witherspoon:~# busctl call \ xyz.openbmc_project.ObjectMapper \ /xyz/openbmc_project/object_mapper \ xyz.openbmc_project.ObjectMapper \ GetObject sas \ /xyz/openbmc_project/led/groups/ \ 1 \ org.freedesktop.Dbus.ObjectManager path or object not found: /xyz/openbmc_project/led/groups/ root@witherspoon:~# ``` From `busctl tree` we can see that the objects do actually appear on the bus: root@witherspoon:~# busctl tree ... Service xyz.openbmc_project.LED.GroupManager: └─/xyz └─/xyz/openbmc_project └─/xyz/openbmc_project/led └─/xyz/openbmc_project/led/groups ├─/xyz/openbmc_project/led/groups/bmc_booted ├─/xyz/openbmc_project/led/groups/bmc_fault ├─/xyz/openbmc_project/led/groups/boxelder_fault ├─/xyz/openbmc_project/led/groups/core0_fault ├─/xyz/openbmc_project/led/groups/core10_fault ... ``` However, the /xyz/openbmc_project/led/groups/ path represents a subtree root, not a leaf element. I didn't realise this was a supported use-case, and over-aggressively removed support for it in the recent patch adding the flat dict cache. Add in a fallback to iterating the PathTree datastructure when we take a cache miss. Change-Id: I658c3fdd6b87be9d814c59a654e63ec5bb83e2bd Fixes: 52aeb314c0eb ("pathtree: Cache keys in a flat dict for fast lookup") Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
-rw-r--r--obmc/utils/pathtree.py5
1 files changed, 4 insertions, 1 deletions
diff --git a/obmc/utils/pathtree.py b/obmc/utils/pathtree.py
index dc48609..9896bfe 100644
--- a/obmc/utils/pathtree.py
+++ b/obmc/utils/pathtree.py
@@ -157,7 +157,10 @@ class PathTree:
d[elements[-1]].update({kids: children, 'data': value})
def __getitem__(self, key):
- return self.cache[key]
+ if key in self.cache:
+ return self.cache[key]
+
+ return self._get_node(key).get('data')
def setdefault(self, key, default):
if not self.get(key):
OpenPOWER on IntegriCloud