1650ab98dSLluís Vilanova# -*- coding: utf-8 -*- 2650ab98dSLluís Vilanova 3650ab98dSLluís Vilanova""" 4650ab98dSLluís VilanovaMachinery for generating tracing-related intermediate files. 5650ab98dSLluís Vilanova""" 6650ab98dSLluís Vilanova 7650ab98dSLluís Vilanova__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>" 8864a2178SLluís Vilanova__copyright__ = "Copyright 2012-2017, Lluís Vilanova <vilanova@ac.upc.edu>" 9650ab98dSLluís Vilanova__license__ = "GPL version 2 or (at your option) any later version" 10650ab98dSLluís Vilanova 11650ab98dSLluís Vilanova__maintainer__ = "Stefan Hajnoczi" 12f892b494SPhilippe Mathieu-Daudé__email__ = "stefanha@redhat.com" 13650ab98dSLluís Vilanova 14650ab98dSLluís Vilanova 15650ab98dSLluís Vilanovaimport re 16650ab98dSLluís Vilanovaimport sys 17b55835acSLluís Vilanovaimport weakref 18650ab98dSLluís Vilanova 19650ab98dSLluís Vilanovaimport tracetool.format 20650ab98dSLluís Vilanovaimport tracetool.backend 21650ab98dSLluís Vilanova 22650ab98dSLluís Vilanova 23650ab98dSLluís Vilanovadef error_write(*lines): 24650ab98dSLluís Vilanova """Write a set of error lines.""" 25650ab98dSLluís Vilanova sys.stderr.writelines("\n".join(lines) + "\n") 26650ab98dSLluís Vilanova 27650ab98dSLluís Vilanovadef error(*lines): 28650ab98dSLluís Vilanova """Write a set of error lines and exit.""" 29650ab98dSLluís Vilanova error_write(*lines) 30650ab98dSLluís Vilanova sys.exit(1) 31650ab98dSLluís Vilanova 32650ab98dSLluís Vilanova 33294170c1SStefan Hajnocziout_lineno = 1 34c05012a3SStefan Hajnocziout_filename = '<none>' 35c05012a3SStefan Hajnocziout_fobj = sys.stdout 36c05012a3SStefan Hajnoczi 37c05012a3SStefan Hajnoczidef out_open(filename): 38c05012a3SStefan Hajnoczi global out_filename, out_fobj 39c05012a3SStefan Hajnoczi out_filename = filename 40c05012a3SStefan Hajnoczi out_fobj = open(filename, 'wt') 41c05012a3SStefan Hajnoczi 42650ab98dSLluís Vilanovadef out(*lines, **kwargs): 43650ab98dSLluís Vilanova """Write a set of output lines. 44650ab98dSLluís Vilanova 4565fdb3ccSzhaolichang You can use kwargs as a shorthand for mapping variables when formatting all 46650ab98dSLluís Vilanova the strings in lines. 47c05012a3SStefan Hajnoczi 48294170c1SStefan Hajnoczi The 'out_lineno' kwarg is automatically added to reflect the current output 49294170c1SStefan Hajnoczi file line number. The 'out_next_lineno' kwarg is also automatically added 50294170c1SStefan Hajnoczi with the next output line number. The 'out_filename' kwarg is automatically 51294170c1SStefan Hajnoczi added with the output filename. 52650ab98dSLluís Vilanova """ 53294170c1SStefan Hajnoczi global out_lineno 54c05012a3SStefan Hajnoczi output = [] 55c05012a3SStefan Hajnoczi for l in lines: 56294170c1SStefan Hajnoczi kwargs['out_lineno'] = out_lineno 57294170c1SStefan Hajnoczi kwargs['out_next_lineno'] = out_lineno + 1 58c05012a3SStefan Hajnoczi kwargs['out_filename'] = out_filename 59c05012a3SStefan Hajnoczi output.append(l % kwargs) 60294170c1SStefan Hajnoczi out_lineno += 1 61c05012a3SStefan Hajnoczi 62c05012a3SStefan Hajnoczi out_fobj.writelines("\n".join(output) + "\n") 63650ab98dSLluís Vilanova 6473ff0610SDaniel P. Berrangé# We only want to allow standard C types or fixed sized 6573ff0610SDaniel P. Berrangé# integer types. We don't want QEMU specific types 6673ff0610SDaniel P. Berrangé# as we can't assume trace backends can resolve all the 6773ff0610SDaniel P. Berrangé# typedefs 6873ff0610SDaniel P. BerrangéALLOWED_TYPES = [ 6973ff0610SDaniel P. Berrangé "int", 7073ff0610SDaniel P. Berrangé "long", 7173ff0610SDaniel P. Berrangé "short", 7273ff0610SDaniel P. Berrangé "char", 7373ff0610SDaniel P. Berrangé "bool", 7473ff0610SDaniel P. Berrangé "unsigned", 7573ff0610SDaniel P. Berrangé "signed", 7673ff0610SDaniel P. Berrangé "int8_t", 7773ff0610SDaniel P. Berrangé "uint8_t", 7873ff0610SDaniel P. Berrangé "int16_t", 7973ff0610SDaniel P. Berrangé "uint16_t", 8073ff0610SDaniel P. Berrangé "int32_t", 8173ff0610SDaniel P. Berrangé "uint32_t", 8273ff0610SDaniel P. Berrangé "int64_t", 8373ff0610SDaniel P. Berrangé "uint64_t", 8473ff0610SDaniel P. Berrangé "void", 8573ff0610SDaniel P. Berrangé "size_t", 8673ff0610SDaniel P. Berrangé "ssize_t", 8773ff0610SDaniel P. Berrangé "uintptr_t", 8873ff0610SDaniel P. Berrangé "ptrdiff_t", 8973ff0610SDaniel P. Berrangé] 9073ff0610SDaniel P. Berrangé 9173ff0610SDaniel P. Berrangédef validate_type(name): 9273ff0610SDaniel P. Berrangé bits = name.split(" ") 9373ff0610SDaniel P. Berrangé for bit in bits: 944d96307cSMarc-André Lureau bit = re.sub(r"\*", "", bit) 9573ff0610SDaniel P. Berrangé if bit == "": 9673ff0610SDaniel P. Berrangé continue 9773ff0610SDaniel P. Berrangé if bit == "const": 9873ff0610SDaniel P. Berrangé continue 9973ff0610SDaniel P. Berrangé if bit not in ALLOWED_TYPES: 10054fa79b7SPhilippe Mathieu-Daudé raise ValueError("Argument type '%s' is not allowed. " 10173ff0610SDaniel P. Berrangé "Only standard C types and fixed size integer " 10273ff0610SDaniel P. Berrangé "types should be used. struct, union, and " 10373ff0610SDaniel P. Berrangé "other complex pointer types should be " 10473ff0610SDaniel P. Berrangé "declared as 'void *'" % name) 105650ab98dSLluís Vilanova 106650ab98dSLluís Vilanovaclass Arguments: 107650ab98dSLluís Vilanova """Event arguments description.""" 108650ab98dSLluís Vilanova 109650ab98dSLluís Vilanova def __init__(self, args): 110650ab98dSLluís Vilanova """ 111650ab98dSLluís Vilanova Parameters 112650ab98dSLluís Vilanova ---------- 113650ab98dSLluís Vilanova args : 1143596f524SLluís Vilanova List of (type, name) tuples or Arguments objects. 115650ab98dSLluís Vilanova """ 1163596f524SLluís Vilanova self._args = [] 1173596f524SLluís Vilanova for arg in args: 1183596f524SLluís Vilanova if isinstance(arg, Arguments): 1193596f524SLluís Vilanova self._args.extend(arg._args) 1203596f524SLluís Vilanova else: 1213596f524SLluís Vilanova self._args.append(arg) 122650ab98dSLluís Vilanova 123ad7443e4SLluís Vilanova def copy(self): 124ad7443e4SLluís Vilanova """Create a new copy.""" 125ad7443e4SLluís Vilanova return Arguments(list(self._args)) 126ad7443e4SLluís Vilanova 127650ab98dSLluís Vilanova @staticmethod 128650ab98dSLluís Vilanova def build(arg_str): 129650ab98dSLluís Vilanova """Build and Arguments instance from an argument string. 130650ab98dSLluís Vilanova 131650ab98dSLluís Vilanova Parameters 132650ab98dSLluís Vilanova ---------- 133650ab98dSLluís Vilanova arg_str : str 134650ab98dSLluís Vilanova String describing the event arguments. 135650ab98dSLluís Vilanova """ 136650ab98dSLluís Vilanova res = [] 137650ab98dSLluís Vilanova for arg in arg_str.split(","): 138650ab98dSLluís Vilanova arg = arg.strip() 13924f4d3d3SStefan Hajnoczi if not arg: 14024f4d3d3SStefan Hajnoczi raise ValueError("Empty argument (did you forget to use 'void'?)") 141b3ef0adeSStefan Hajnoczi if arg == 'void': 142650ab98dSLluís Vilanova continue 143b3ef0adeSStefan Hajnoczi 144b3ef0adeSStefan Hajnoczi if '*' in arg: 145b3ef0adeSStefan Hajnoczi arg_type, identifier = arg.rsplit('*', 1) 146b3ef0adeSStefan Hajnoczi arg_type += '*' 147b3ef0adeSStefan Hajnoczi identifier = identifier.strip() 148b3ef0adeSStefan Hajnoczi else: 149b3ef0adeSStefan Hajnoczi arg_type, identifier = arg.rsplit(None, 1) 150b3ef0adeSStefan Hajnoczi 15173ff0610SDaniel P. Berrangé validate_type(arg_type) 152b3ef0adeSStefan Hajnoczi res.append((arg_type, identifier)) 153650ab98dSLluís Vilanova return Arguments(res) 154650ab98dSLluís Vilanova 1553596f524SLluís Vilanova def __getitem__(self, index): 1563596f524SLluís Vilanova if isinstance(index, slice): 1573596f524SLluís Vilanova return Arguments(self._args[index]) 1583596f524SLluís Vilanova else: 1593596f524SLluís Vilanova return self._args[index] 1603596f524SLluís Vilanova 161650ab98dSLluís Vilanova def __iter__(self): 162650ab98dSLluís Vilanova """Iterate over the (type, name) pairs.""" 163650ab98dSLluís Vilanova return iter(self._args) 164650ab98dSLluís Vilanova 165650ab98dSLluís Vilanova def __len__(self): 166650ab98dSLluís Vilanova """Number of arguments.""" 167650ab98dSLluís Vilanova return len(self._args) 168650ab98dSLluís Vilanova 169650ab98dSLluís Vilanova def __str__(self): 170650ab98dSLluís Vilanova """String suitable for declaring function arguments.""" 171650ab98dSLluís Vilanova if len(self._args) == 0: 172650ab98dSLluís Vilanova return "void" 173650ab98dSLluís Vilanova else: 174650ab98dSLluís Vilanova return ", ".join([ " ".join([t, n]) for t,n in self._args ]) 175650ab98dSLluís Vilanova 176650ab98dSLluís Vilanova def __repr__(self): 177650ab98dSLluís Vilanova """Evaluable string representation for this object.""" 178650ab98dSLluís Vilanova return "Arguments(\"%s\")" % str(self) 179650ab98dSLluís Vilanova 180650ab98dSLluís Vilanova def names(self): 181650ab98dSLluís Vilanova """List of argument names.""" 182650ab98dSLluís Vilanova return [ name for _, name in self._args ] 183650ab98dSLluís Vilanova 184650ab98dSLluís Vilanova def types(self): 185650ab98dSLluís Vilanova """List of argument types.""" 186650ab98dSLluís Vilanova return [ type_ for type_, _ in self._args ] 187650ab98dSLluís Vilanova 188bc9beb47SLluís Vilanova def casted(self): 189bc9beb47SLluís Vilanova """List of argument names casted to their type.""" 190bc9beb47SLluís Vilanova return ["(%s)%s" % (type_, name) for type_, name in self._args] 191bc9beb47SLluís Vilanova 192650ab98dSLluís Vilanova 193650ab98dSLluís Vilanovaclass Event(object): 194650ab98dSLluís Vilanova """Event description. 195650ab98dSLluís Vilanova 196650ab98dSLluís Vilanova Attributes 197650ab98dSLluís Vilanova ---------- 198650ab98dSLluís Vilanova name : str 199650ab98dSLluís Vilanova The event name. 200650ab98dSLluís Vilanova fmt : str 201650ab98dSLluís Vilanova The event format string. 202650ab98dSLluís Vilanova properties : set(str) 203650ab98dSLluís Vilanova Properties of the event. 204650ab98dSLluís Vilanova args : Arguments 205650ab98dSLluís Vilanova The event arguments. 2064e66c9efSStefan Hajnoczi lineno : int 2074e66c9efSStefan Hajnoczi The line number in the input file. 2084e66c9efSStefan Hajnoczi filename : str 2094e66c9efSStefan Hajnoczi The path to the input file. 21023214429SLluís Vilanova 211650ab98dSLluís Vilanova """ 212650ab98dSLluís Vilanova 213e6d8e5e6SPaolo Bonzini _CRE = re.compile(r"((?P<props>[\w\s]+)\s+)?" 214e6d8e5e6SPaolo Bonzini r"(?P<name>\w+)" 215e6d8e5e6SPaolo Bonzini r"\((?P<args>[^)]*)\)" 216e6d8e5e6SPaolo Bonzini r"\s*" 217e6d8e5e6SPaolo Bonzini r"(?:(?:(?P<fmt_trans>\".+),)?\s*(?P<fmt>\".+))?" 218e6d8e5e6SPaolo Bonzini r"\s*") 219650ab98dSLluís Vilanova 220126d4123SAlex Bennée _VALID_PROPS = set(["disable", "vcpu"]) 221650ab98dSLluís Vilanova 2224e66c9efSStefan Hajnoczi def __init__(self, name, props, fmt, args, lineno, filename, orig=None, 2234ade0541SLluís Vilanova event_trans=None, event_exec=None): 224650ab98dSLluís Vilanova """ 225650ab98dSLluís Vilanova Parameters 226650ab98dSLluís Vilanova ---------- 227650ab98dSLluís Vilanova name : string 228650ab98dSLluís Vilanova Event name. 229650ab98dSLluís Vilanova props : list of str 230650ab98dSLluís Vilanova Property names. 231b2b36c22SLluís Vilanova fmt : str, list of str 2326e497fa1SStefan Hajnoczi Event printing format string(s). 233650ab98dSLluís Vilanova args : Arguments 234650ab98dSLluís Vilanova Event arguments. 2354e66c9efSStefan Hajnoczi lineno : int 2364e66c9efSStefan Hajnoczi The line number in the input file. 2374e66c9efSStefan Hajnoczi filename : str 2384e66c9efSStefan Hajnoczi The path to the input file. 239b55835acSLluís Vilanova orig : Event or None 2404ade0541SLluís Vilanova Original Event before transformation/generation. 2414ade0541SLluís Vilanova event_trans : Event or None 2424ade0541SLluís Vilanova Generated translation-time event ("tcg" property). 2434ade0541SLluís Vilanova event_exec : Event or None 2444ade0541SLluís Vilanova Generated execution-time event ("tcg" property). 24541ef7b00SAlex Bennée 246650ab98dSLluís Vilanova """ 247650ab98dSLluís Vilanova self.name = name 248650ab98dSLluís Vilanova self.properties = props 249650ab98dSLluís Vilanova self.fmt = fmt 250650ab98dSLluís Vilanova self.args = args 2514e66c9efSStefan Hajnoczi self.lineno = int(lineno) 2524e66c9efSStefan Hajnoczi self.filename = str(filename) 2534ade0541SLluís Vilanova self.event_trans = event_trans 2544ade0541SLluís Vilanova self.event_exec = event_exec 255650ab98dSLluís Vilanova 256f3fddaf6SDaniel P. Berrange if len(args) > 10: 257f3fddaf6SDaniel P. Berrange raise ValueError("Event '%s' has more than maximum permitted " 258f3fddaf6SDaniel P. Berrange "argument count" % name) 259f3fddaf6SDaniel P. Berrange 260b55835acSLluís Vilanova if orig is None: 261b55835acSLluís Vilanova self.original = weakref.ref(self) 262b55835acSLluís Vilanova else: 263b55835acSLluís Vilanova self.original = orig 264b55835acSLluís Vilanova 265650ab98dSLluís Vilanova unknown_props = set(self.properties) - self._VALID_PROPS 266650ab98dSLluís Vilanova if len(unknown_props) > 0: 2679c24a52eSLluís Vilanova raise ValueError("Unknown properties: %s" 2689c24a52eSLluís Vilanova % ", ".join(unknown_props)) 269b2b36c22SLluís Vilanova assert isinstance(self.fmt, str) or len(self.fmt) == 2 270650ab98dSLluís Vilanova 271ad7443e4SLluís Vilanova def copy(self): 272ad7443e4SLluís Vilanova """Create a new copy.""" 273ad7443e4SLluís Vilanova return Event(self.name, list(self.properties), self.fmt, 2744e66c9efSStefan Hajnoczi self.args.copy(), self.lineno, self.filename, 2754e66c9efSStefan Hajnoczi self, self.event_trans, self.event_exec) 276ad7443e4SLluís Vilanova 277650ab98dSLluís Vilanova @staticmethod 2784e66c9efSStefan Hajnoczi def build(line_str, lineno, filename): 279650ab98dSLluís Vilanova """Build an Event instance from a string. 280650ab98dSLluís Vilanova 281650ab98dSLluís Vilanova Parameters 282650ab98dSLluís Vilanova ---------- 283650ab98dSLluís Vilanova line_str : str 284650ab98dSLluís Vilanova Line describing the event. 2854e66c9efSStefan Hajnoczi lineno : int 2864e66c9efSStefan Hajnoczi Line number in input file. 2874e66c9efSStefan Hajnoczi filename : str 2884e66c9efSStefan Hajnoczi Path to input file. 289650ab98dSLluís Vilanova """ 290650ab98dSLluís Vilanova m = Event._CRE.match(line_str) 291650ab98dSLluís Vilanova assert m is not None 292650ab98dSLluís Vilanova groups = m.groupdict('') 293650ab98dSLluís Vilanova 294650ab98dSLluís Vilanova name = groups["name"] 295650ab98dSLluís Vilanova props = groups["props"].split() 296650ab98dSLluís Vilanova fmt = groups["fmt"] 297b2b36c22SLluís Vilanova fmt_trans = groups["fmt_trans"] 298772f1b37SDaniel P. Berrangé if fmt.find("%m") != -1 or fmt_trans.find("%m") != -1: 299772f1b37SDaniel P. Berrangé raise ValueError("Event format '%m' is forbidden, pass the error " 300772f1b37SDaniel P. Berrangé "as an explicit trace argument") 3019f7ad79cSPhilippe Mathieu-Daudé if fmt.endswith(r'\n"'): 3029f7ad79cSPhilippe Mathieu-Daudé raise ValueError("Event format must not end with a newline " 3039f7ad79cSPhilippe Mathieu-Daudé "character") 304*4c2b6f32SPhilippe Mathieu-Daudé if '\\n' in fmt: 305*4c2b6f32SPhilippe Mathieu-Daudé raise ValueError("Event format must not use new line character") 306772f1b37SDaniel P. Berrangé 307b2b36c22SLluís Vilanova if len(fmt_trans) > 0: 308b2b36c22SLluís Vilanova fmt = [fmt_trans, fmt] 309650ab98dSLluís Vilanova args = Arguments.build(groups["args"]) 310650ab98dSLluís Vilanova 3110e2b9edfSPhilippe Mathieu-Daudé return Event(name, props, fmt, args, lineno, filename) 312650ab98dSLluís Vilanova 313650ab98dSLluís Vilanova def __repr__(self): 314650ab98dSLluís Vilanova """Evaluable string representation for this object.""" 315b2b36c22SLluís Vilanova if isinstance(self.fmt, str): 316b2b36c22SLluís Vilanova fmt = self.fmt 317b2b36c22SLluís Vilanova else: 318b2b36c22SLluís Vilanova fmt = "%s, %s" % (self.fmt[0], self.fmt[1]) 319650ab98dSLluís Vilanova return "Event('%s %s(%s) %s')" % (" ".join(self.properties), 320650ab98dSLluís Vilanova self.name, 321650ab98dSLluís Vilanova self.args, 322b2b36c22SLluís Vilanova fmt) 323fb1a66bcSJon Emil Jahren # Star matching on PRI is dangerous as one might have multiple 324fb1a66bcSJon Emil Jahren # arguments with that format, hence the non-greedy version of it. 325e6d8e5e6SPaolo Bonzini _FMT = re.compile(r"(%[\d\.]*\w+|%.*?PRI\S+)") 32623214429SLluís Vilanova 32723214429SLluís Vilanova def formats(self): 3286e497fa1SStefan Hajnoczi """List conversion specifiers in the argument print format string.""" 32923214429SLluís Vilanova assert not isinstance(self.fmt, list) 33023214429SLluís Vilanova return self._FMT.findall(self.fmt) 33123214429SLluís Vilanova 3327d08f0daSLluís Vilanova QEMU_TRACE = "trace_%(name)s" 333864a2178SLluís Vilanova QEMU_TRACE_NOCHECK = "_nocheck__" + QEMU_TRACE 334707c8a98SLluís Vilanova QEMU_TRACE_TCG = QEMU_TRACE + "_tcg" 33593977402SDaniel P. Berrange QEMU_DSTATE = "_TRACE_%(NAME)s_DSTATE" 3363932ef3fSStefan Hajnoczi QEMU_BACKEND_DSTATE = "TRACE_%(NAME)s_BACKEND_DSTATE" 33779218be4SDaniel P. Berrange QEMU_EVENT = "_TRACE_%(NAME)s_EVENT" 3387d08f0daSLluís Vilanova 3397d08f0daSLluís Vilanova def api(self, fmt=None): 3407d08f0daSLluís Vilanova if fmt is None: 3417d08f0daSLluís Vilanova fmt = Event.QEMU_TRACE 34293977402SDaniel P. Berrange return fmt % {"name": self.name, "NAME": self.name.upper()} 3437d08f0daSLluís Vilanova 3447d08f0daSLluís Vilanova 34586b5aacfSDaniel P. Berrangédef read_events(fobj, fname): 346d1b97bceSDaniel P. Berrange """Generate the output for the given (format, backends) pair. 347d1b97bceSDaniel P. Berrange 348d1b97bceSDaniel P. Berrange Parameters 349d1b97bceSDaniel P. Berrange ---------- 350d1b97bceSDaniel P. Berrange fobj : file 351d1b97bceSDaniel P. Berrange Event description file. 35286b5aacfSDaniel P. Berrangé fname : str 35386b5aacfSDaniel P. Berrangé Name of event file 354d1b97bceSDaniel P. Berrange 355d1b97bceSDaniel P. Berrange Returns a list of Event objects 356d1b97bceSDaniel P. Berrange """ 357d1b97bceSDaniel P. Berrange 358776ec96fSChristoph Seifert events = [] 3595069b561SStefan Hajnoczi for lineno, line in enumerate(fobj, 1): 36077606363SDaniel P. Berrangé if line[-1] != '\n': 36177606363SDaniel P. Berrangé raise ValueError("%s does not end with a new line" % fname) 362650ab98dSLluís Vilanova if not line.strip(): 363650ab98dSLluís Vilanova continue 364650ab98dSLluís Vilanova if line.lstrip().startswith('#'): 365650ab98dSLluís Vilanova continue 366776ec96fSChristoph Seifert 3675069b561SStefan Hajnoczi try: 3684e66c9efSStefan Hajnoczi event = Event.build(line, lineno, fname) 3695069b561SStefan Hajnoczi except ValueError as e: 37086b5aacfSDaniel P. Berrangé arg0 = 'Error at %s:%d: %s' % (fname, lineno, e.args[0]) 3715069b561SStefan Hajnoczi e.args = (arg0,) + e.args[1:] 3725069b561SStefan Hajnoczi raise 373776ec96fSChristoph Seifert 374776ec96fSChristoph Seifert events.append(event) 375776ec96fSChristoph Seifert 376776ec96fSChristoph Seifert return events 377650ab98dSLluís Vilanova 378650ab98dSLluís Vilanova 379650ab98dSLluís Vilanovaclass TracetoolError (Exception): 380650ab98dSLluís Vilanova """Exception for calls to generate.""" 381650ab98dSLluís Vilanova pass 382650ab98dSLluís Vilanova 383650ab98dSLluís Vilanova 384650ab98dSLluís Vilanovadef try_import(mod_name, attr_name=None, attr_default=None): 385650ab98dSLluís Vilanova """Try to import a module and get an attribute from it. 386650ab98dSLluís Vilanova 387650ab98dSLluís Vilanova Parameters 388650ab98dSLluís Vilanova ---------- 389650ab98dSLluís Vilanova mod_name : str 390650ab98dSLluís Vilanova Module name. 391650ab98dSLluís Vilanova attr_name : str, optional 392650ab98dSLluís Vilanova Name of an attribute in the module. 393650ab98dSLluís Vilanova attr_default : optional 394650ab98dSLluís Vilanova Default value if the attribute does not exist in the module. 395650ab98dSLluís Vilanova 396650ab98dSLluís Vilanova Returns 397650ab98dSLluís Vilanova ------- 398650ab98dSLluís Vilanova A pair indicating whether the module could be imported and the module or 399650ab98dSLluís Vilanova object or attribute value. 400650ab98dSLluís Vilanova """ 401650ab98dSLluís Vilanova try: 40245d6c787SStefan Hajnoczi module = __import__(mod_name, globals(), locals(), ["__package__"]) 403650ab98dSLluís Vilanova if attr_name is None: 404650ab98dSLluís Vilanova return True, module 405650ab98dSLluís Vilanova return True, getattr(module, str(attr_name), attr_default) 406650ab98dSLluís Vilanova except ImportError: 407650ab98dSLluís Vilanova return False, None 408650ab98dSLluís Vilanova 409650ab98dSLluís Vilanova 41080dd5c49SDaniel P. Berrangedef generate(events, group, format, backends, 41152ef093aSLluís Vilanova binary=None, probe_prefix=None): 4125b808275SLluís Vilanova """Generate the output for the given (format, backends) pair. 413650ab98dSLluís Vilanova 414650ab98dSLluís Vilanova Parameters 415650ab98dSLluís Vilanova ---------- 4169096b78aSDaniel P. Berrange events : list 4179096b78aSDaniel P. Berrange list of Event objects to generate for 41880dd5c49SDaniel P. Berrange group: str 41980dd5c49SDaniel P. Berrange Name of the tracing group 420650ab98dSLluís Vilanova format : str 421650ab98dSLluís Vilanova Output format name. 4225b808275SLluís Vilanova backends : list 4235b808275SLluís Vilanova Output backend names. 42452ef093aSLluís Vilanova binary : str or None 42552ef093aSLluís Vilanova See tracetool.backend.dtrace.BINARY. 42652ef093aSLluís Vilanova probe_prefix : str or None 42752ef093aSLluís Vilanova See tracetool.backend.dtrace.PROBEPREFIX. 428650ab98dSLluís Vilanova """ 429650ab98dSLluís Vilanova # fix strange python error (UnboundLocalError tracetool) 430650ab98dSLluís Vilanova import tracetool 431650ab98dSLluís Vilanova 432650ab98dSLluís Vilanova format = str(format) 433403e11edSStefan Hajnoczi if len(format) == 0: 434650ab98dSLluís Vilanova raise TracetoolError("format not set") 43553158adcSLluís Vilanova if not tracetool.format.exists(format): 436650ab98dSLluís Vilanova raise TracetoolError("unknown format: %s" % format) 437650ab98dSLluís Vilanova 438403e11edSStefan Hajnoczi if len(backends) == 0: 4395b808275SLluís Vilanova raise TracetoolError("no backends specified") 4405b808275SLluís Vilanova for backend in backends: 44153158adcSLluís Vilanova if not tracetool.backend.exists(backend): 442650ab98dSLluís Vilanova raise TracetoolError("unknown backend: %s" % backend) 4435b808275SLluís Vilanova backend = tracetool.backend.Wrapper(backends, format) 444650ab98dSLluís Vilanova 44552ef093aSLluís Vilanova import tracetool.backend.dtrace 44652ef093aSLluís Vilanova tracetool.backend.dtrace.BINARY = binary 44752ef093aSLluís Vilanova tracetool.backend.dtrace.PROBEPREFIX = probe_prefix 44852ef093aSLluís Vilanova 44980dd5c49SDaniel P. Berrange tracetool.format.generate(events, format, backend, group) 450