diff options
author | Alban Crequy <alban.crequy@collabora.co.uk> | 2014-10-02 14:21:24 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-10-06 12:10:51 +0100 |
commit | 668cd4eb20bc2e7989d96d9b8cdea42edc6221a9 (patch) | |
tree | 0bdfc1f2fab8d29b8809a653ff4b764b738ffa26 /tools | |
parent | 33ee25f98af863e9355fd53b9184c0b798343b89 (diff) |
GetAllMatchRules: provide an example how it could be used
[use dist_examples_SCRIPTS instead of EXTRA_DIST -smcv]
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=84598
Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/GetAllMatchRules.py | 112 | ||||
-rw-r--r-- | tools/Makefile.am | 5 |
2 files changed, 117 insertions, 0 deletions
diff --git a/tools/GetAllMatchRules.py b/tools/GetAllMatchRules.py new file mode 100755 index 00000000..6a7e4cd9 --- /dev/null +++ b/tools/GetAllMatchRules.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python + +import sys +import argparse +import dbus +import time + +def get_cmdline(pid): + cmdline = '' + if pid > 0: + try: + procpath = '/proc/' + str(pid) + '/cmdline' + with open(procpath, 'r') as f: + cmdline = " ".join(f.readline().split('\0')) + except: + pass + return cmdline + +# Parsing parameters + +parser = argparse.ArgumentParser(description='Testing D-Bus match rules') +parser.add_argument('--session', help='session bus', action="store_true") +parser.add_argument('--system', help='system bus', action="store_true") +parser.add_argument('--all', help='print all match rules', action="store_true") +args = parser.parse_args() + +if args.system and args.session: + parser.print_help() + sys.exit(1) + +# Fetch data from the bus driver + +if args.system: + bus = dbus.SystemBus() +else: + bus = dbus.SessionBus() + +remote_object = bus.get_object("org.freedesktop.DBus", + "/org/freedesktop/DBus") +bus_iface = dbus.Interface(remote_object, "org.freedesktop.DBus") +stats_iface = dbus.Interface(remote_object, "org.freedesktop.DBus.Debug.Stats") + +try: + match_rules = stats_iface.GetAllMatchRules() +except: + print("GetConnectionMatchRules failed: did you enable the Stats interface?") + sys.exit(1) + +names = bus_iface.ListNames() +unique_names = [ a for a in names if a.startswith(":") ] +pids = dict((name, bus_iface.GetConnectionUnixProcessID(name)) for name in unique_names) +cmds = dict((name, get_cmdline(pids[name])) for name in unique_names) +well_known_names = [ a for a in names if a not in unique_names ] +owners = dict((wkn, bus_iface.GetNameOwner(wkn)) for wkn in well_known_names) + +rules = dict((k_rules, + dict({ + 'wkn': [k for k, v in owners.items() if v == k_rules], + 'pid': pids[k_rules], + 'cmd': cmds[k_rules] or "", + 'rules': v_rules, + 'warnings': dict({ + 'not_signal': [a for a in v_rules if "type='signal'" not in a], + 'no_sender': [a for a in v_rules if "sender=" not in a], + 'local': [a for a in v_rules if "org.freedesktop.DBus.Local" in a], + 'NameOwnerChanged_arg0': [a for a in v_rules if "member='NameOwnerChanged'" in a and "arg0" not in a] + }) + }) + ) for k_rules, v_rules in match_rules.items()) + +warnings = dict({ + 'not_signal': 'Match rule without selecting signals', + 'no_sender': 'Match rule without a sender criteria', + 'local': 'Match rule on the org.freedesktop.DBus.Local interface', + 'NameOwnerChanged_arg0': 'Match rule on NameOwnerChanged without a arg0* criteria' + }) + +# Print the match rules + +# print all match rules without analysing them +if args.all: + for name in rules: + print("Connection %s with pid %d '%s' (%s): %d match rules, %d warnings" + % (name, rules[name]['pid'], rules[name]['cmd'], + ' '.join(rules[name]['wkn']), len(rules[name]['rules']), + len(sum(rules[name]['warnings'].values(), [])))) + for rule in rules[name]['rules']: + print("\t%s" % (rule)) + print("") + sys.exit(0) + +# analyse match rules and print only the suspicious ones +for conn,data in rules.items(): + warnings_count = len(sum(data['warnings'].values(), [])) + if warnings_count == 0: + continue + + print("Connection %s with pid %d '%s' (%s): %d match rules, %d warnings" + % (conn, data['pid'], data['cmd'], ' '.join(data['wkn']), + len(data['rules']), warnings_count)) + + for warn_code,rule_list in [(warn_code,rule_list) \ + for warn_code, rule_list \ + in data['warnings'].items() \ + if len(rule_list) > 0]: + print(" - %s:" % (warnings[warn_code])) + for rule in rule_list: + print(" - %s" % (rule)) + + print("") + +sys.exit(0) diff --git a/tools/Makefile.am b/tools/Makefile.am index 73d95fcf..2ec19eda 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -76,6 +76,11 @@ dbus_launch_LDADD = \ $(DBUS_X_LIBS) \ $(NULL) +examplesdir = ${docdir}/examples +dist_examples_SCRIPTS = \ + GetAllMatchRules.py \ + $(NULL) + EXTRA_DIST = run-with-tmp-session-bus.sh strtoll.c strtoull.c CLEANFILES = \ run-with-tmp-session-bus.conf |