1
0
mirror of https://github.com/ARM-software/devlib.git synced 2025-02-07 05:30:44 +00:00

Target: add read_tree_values and read_tree_values_flat

Add two new methods to target that allow querying values of all sysfs
nodes in a sub-directory structure all at once. The difference is that
read_tree_values_flat returns a flat dict of path->value mappings;
read_tree_values returns a nested dict structure that mimics the
scanned sub-directories tree.
This commit is contained in:
Sergei Trofimov 2017-10-03 16:28:09 +01:00
parent 92fb54d57b
commit 181bc180c4
3 changed files with 88 additions and 0 deletions

View File

@ -195,6 +195,22 @@ cgroups_freezer_set_state() {
exit 1 exit 1
} }
################################################################################
# Misc
################################################################################
read_tree_values() {
PATH=$1
MAXDEPTH=$2
PATHS=$($BUSYBOX find $PATH -follow -maxdepth $MAXDEPTH)
if [ ${#PATHS[@]} -eq 0 ]; then
echo "ERROR: '$1' does not exist"
else
$BUSYBOX grep -s '' $PATHS
fi
}
################################################################################ ################################################################################
# Main Function Dispatcher # Main Function Dispatcher
################################################################################ ################################################################################
@ -236,6 +252,9 @@ cgroups_freezer_set_state)
ftrace_get_function_stats) ftrace_get_function_stats)
ftrace_get_function_stats ftrace_get_function_stats
;; ;;
read_tree_values)
read_tree_values $*
;;
*) *)
echo "Command [$CMD] not supported" echo "Command [$CMD] not supported"
exit -1 exit -1

View File

@ -614,6 +614,20 @@ class Target(object):
timeout = duration + 10 timeout = duration + 10
self.execute('sleep {}'.format(duration), timeout=timeout) self.execute('sleep {}'.format(duration), timeout=timeout)
def read_tree_values_flat(self, path, depth=1, check_exit_code=True):
command = 'read_tree_values {} {}'.format(path, depth)
output = self._execute_util(command, as_root=self.is_rooted,
check_exit_code=check_exit_code)
result = {}
for entry in output.strip().split('\n'):
path, value = entry.strip().split(':', 1)
result[path] = value
return result
def read_tree_values(self, path, depth=1, dictcls=dict, check_exit_code=True):
value_map = self.read_tree_values_flat(path, depth, check_exit_code)
return _build_path_tree(value_map, path, self.path.sep, dictcls)
# internal methods # internal methods
def _setup_shutils(self): def _setup_shutils(self):
@ -1558,3 +1572,32 @@ def _get_part_name(section):
if name is None: if name is None:
name = '{}/{}/{}'.format(implementer, part, variant) name = '{}/{}/{}'.format(implementer, part, variant)
return name return name
def _build_path_tree(path_map, basepath, sep=os.path.sep, dictcls=dict):
"""
Convert a flat mapping of paths to values into a nested structure of
dict-line object (``dict``'s by default), mirroring the directory hierarchy
represented by the paths relative to ``basepath``.
"""
def process_node(node, path, value):
parts = path.split(sep, 1)
if len(parts) == 1: # leaf
node[parts[0]] = value
else: # branch
if parts[0] not in node:
node[parts[0]] = dictcls()
process_node(node[parts[0]], parts[1], value)
relpath_map = {os.path.relpath(p, basepath): v
for p, v in path_map.iteritems()}
if len(relpath_map) == 1 and relpath_map.keys()[0] == '.':
result = relpath_map.values()[0]
else:
result = dictcls()
for path, value in relpath_map.iteritems():
process_node(result, path, value)
return result

View File

@ -327,6 +327,32 @@ Target
some sysfs entries silently failing to set the written value without some sysfs entries silently failing to set the written value without
returning an error code. returning an error code.
.. method:: Target.read_tree_values(path, depth=1, dictcls=dict):
Read values of all sysfs (or similar) file nodes under ``path``, traversing
up to the maximum depth ``depth``.
Returns a nested structure of dict-like objects (``dict``\ s by default) that
follows the structure of the scanned sub-directory tree. The top-level entry
has a single item who's key is ``path``. If ``path`` points to a single file,
the value of the entry is the value ready from that file node. Otherwise, the
value is a dict-line object with a key for every entry under ``path``
mapping onto its value or further dict-like objects as appropriate.
:param path: sysfs path to scan
:param depth: maximum depth to descend
:param dictcls: a dict-like type to be used for each level of the hierarchy.
.. method:: Target.read_tree_values_flat(path, depth=1):
Read values of all sysfs (or similar) file nodes under ``path``, traversing
up to the maximum depth ``depth``.
Returns a dict mapping paths of file nodes to corresponding values.
:param path: sysfs path to scan
:param depth: maximum depth to descend
.. method:: Target.reset() .. method:: Target.reset()
Soft reset the target. Typically, this means executing ``reboot`` on the Soft reset the target. Typically, this means executing ``reboot`` on the