1# Lint as: python2, python3 2# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5# Lint as: python3 6""" Udevadm helper classes and functions. 7""" 8 9import subprocess 10 11class UdevadmInfo(): 12 """ Use udevadm info on a specific path. 13 """ 14 15 @classmethod 16 def GetProperties(cls, syspath): 17 """ Get all properties of given syspath as a dict. 18 19 Args: 20 syspath: System path to get properties for. 21 22 Returns: 23 Dict with attribute/property as key and it's value. All keys are 24 converted to lowercase. Example: {'subsystem': 'input'} 25 """ 26 props = {} 27 rawprops = subprocess.check_output(' '.join( 28 ['udevadm', 'info', '-q', 'property', '-p', syspath]), 29 shell=True) 30 31 for line in rawprops.splitlines(): 32 upper_key, value = line.split(b'=', 1) 33 props[upper_key.lower()] = value.strip(b'"') 34 35 return props 36 37class UdevadmTrigger(): 38 """ Use udevadm trigger with specific rules. 39 """ 40 41 def __init__(self, 42 verbose=True, 43 event_type=None, 44 attr_match=[], 45 attr_nomatch=[], 46 subsystem_match=[], 47 subsystem_nomatch=[]): 48 """ Constructor 49 50 Args: 51 verbose: Whether to output triggered syspaths 52 event_type: What type of events to trigger (device or subsystem) 53 attr_match: What attributes to match 54 attr_nomatch: What attributes not to match 55 subsystem_match: What subsystems to match 56 subsystem_nomatch: What subsystems not to match 57 """ 58 cmd = ['udevadm', 'trigger'] 59 60 if verbose: 61 cmd.append('-v') 62 63 if event_type: 64 cmd.append('-t') 65 cmd.append('"{}"'.format(event_type)) 66 67 for attr in attr_match: 68 cmd.append('-a') 69 cmd.append('"{}"'.format(attr)) 70 71 for attr in attr_nomatch: 72 cmd.append('-A') 73 cmd.append('"{}"'.format(attr)) 74 75 for subsystem in subsystem_match: 76 cmd.append('-s') 77 cmd.append('"{}"'.format(subsystem)) 78 79 for subsystem in subsystem_nomatch: 80 cmd.append('-S') 81 cmd.append('"{}"'.format(subsystem)) 82 83 self.cmd = cmd 84 85 def DryRun(self): 86 """ Do a dry run using initialized trigger rules. 87 88 Returns: 89 List of syspaths that would be triggered. 90 """ 91 cmd = self.cmd + ['-n'] 92 lines = subprocess.check_output(' '.join(cmd), shell=True) 93 return lines.splitlines() if lines else [] 94