As part of an goal to eliminate Perl from libvirt build tools, rewrite the dtrace2systemtap.pl tool in Python. This was a straight conversion, manually going line-by-line to change the syntax from Perl to Python. Thus the overall structure of the file and approach is the same. Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx> --- Makefile.am | 1 + scripts/dtrace2systemtap.py | 143 ++++++++++++++++++++++++++++++++++++ src/Makefile.am | 10 +-- src/dtrace2systemtap.pl | 130 -------------------------------- 4 files changed, 147 insertions(+), 137 deletions(-) create mode 100755 scripts/dtrace2systemtap.py delete mode 100755 src/dtrace2systemtap.pl diff --git a/Makefile.am b/Makefile.am index c31aec5f45..9dcaaecb6b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -50,6 +50,7 @@ EXTRA_DIST = \ scripts/check-spacing.py \ scripts/check-symfile.py \ scripts/check-symsorting.py \ + scripts/dtrace2systemtap.py \ scripts/header-ifdef.py \ scripts/minimize-po.py \ scripts/mock-noinline.py \ diff --git a/scripts/dtrace2systemtap.py b/scripts/dtrace2systemtap.py new file mode 100755 index 0000000000..922713e599 --- /dev/null +++ b/scripts/dtrace2systemtap.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python +# +# Copyright (C) 2011-2019 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see +# <http://www.gnu.org/licenses/>. +# +# +# Generate a set of systemtap probe definitions corresponding to +# DTrace probe markers in libvirt.so +# +# python dtrace2systemtap.py probes.d > libvirt_probes.stp +# + +from __future__ import print_function + +import re +import sys + +file = None +filelist = [] +files = {} + +bindir = sys.argv[1] +sbindir = sys.argv[2] +libdir = sys.argv[3] +dtrace = sys.argv[4] + +probe = None +args = None + +# Read the DTraceprobes definition + +with open(dtrace, "r") as fh: + lineno = 0 + for line in fh: + lineno = lineno + 1 + line = line.strip() + if line == "": + continue + if line.find("provider ") != -1 and line.find("{") != -1: + continue + if line.find("};") != -1: + continue + + if line.startswith("#"): + m = re.search(r'''^\#\s*file:\s*(\S+)$''', line) + if m is not None: + file = m.group(1) + filelist.append(file) + files[file] = {"prefix": None, "probes": []} + continue + + m = re.search(r'''^\#\s*prefix:\s*(\S+)$''', line) + if m is not None: + files[file]["prefix"] = m.group(1) + continue + + m = re.search(r'''^\#\s*binary:\s*(\S+)$''', line) + if m is not None: + files[file]["binary"] = m.group(1) + continue + + m = re.search(r'''^\#\s*module:\s*(\S+)$''', line) + if m is not None: + files[file]["module"] = m.group(1) + + # ignore unknown comments + else: + m = re.search(r'''probe\s+([a-zA-Z0-9_]+)\((.*?)(\);)?$''', line) + if m is not None: + probe = m.group(1) + args = m.group(2) + if m.group(3) is not None: + files[file]["probes"].append([probe, args]) + probe = None + args = None + elif probe is not None: + m = re.search(r'''^(.*?)(\);)?$''', line) + if m is not None: + args = args + m.group(1) + if m.group(2) is not None: + files[file]["probes"].append([probe, args]) + probe = None + args = None + else: + raise Exception("unexpected data %s on line %d" % + (line, lineno)) + else: + raise Exception("unexpected data %s on line %d" % + (line, lineno)) + +# Write out the SystemTap probes +for file in filelist: + prefix = files[file]["prefix"] + probes = files[file]["probes"] + + print("# %s\n" % file) + for probe in probes: + name = probe[0] + args = probe[1] + + pname = name.replace(prefix + "_", "libvirt." + prefix + ".") + + binary = libdir + "/libvirt.so" + if "binary" in files[file]: + binary = sbindir + "/" + files[file]["binary"] + if "module" in files[file]: + binary = libdir + "/" + files[file]["module"] + + print("probe %s = process(\"%s\").mark(\"%s\") {" % + (pname, binary, name)) + + argbits = args.split(",") + for idx in range(len(argbits)): + arg = argbits[idx] + isstr = False + if arg.find("char *") != -1: + isstr = True + + m = re.search(r'''^.*\s\*?(\S+)$''', arg) + if m is not None: + arg = m.group(1) + else: + raise Exception("Malformed arg %s" % arg) + + if isstr: + print(" %s = user_string($arg%d);" % (arg, idx + 1)) + else: + print(" %s = $arg%d;" % (arg, idx + 1)) + print("}\n") + print("") diff --git a/src/Makefile.am b/src/Makefile.am index 2b04890333..fc155bb037 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -602,7 +602,6 @@ nodist_libvirt_la_SOURCES = libvirt_probes.h if WITH_REMOTE nodist_libvirt_driver_remote_la_SOURCES = libvirt_probes.h endif WITH_REMOTE -DTRACE2SYSTEMTAP_FLAGS = --with-modules BUILT_SOURCES += libvirt_probes.h libvirt_probes.stp libvirt_functions.stp @@ -637,10 +636,10 @@ RPC_PROBE_FILES += $(srcdir)/rpc/virnetprotocol.x \ libvirt_functions.stp: $(RPC_PROBE_FILES) $(srcdir)/rpc/gensystemtap.pl $(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gensystemtap.pl $(RPC_PROBE_FILES) > $@ -%_probes.stp: %_probes.d $(srcdir)/dtrace2systemtap.pl \ +%_probes.stp: %_probes.d $(top_srcdir)/scripts/dtrace2systemtap.py \ $(top_builddir)/config.status - $(AM_V_GEN)$(PERL) -w $(srcdir)/dtrace2systemtap.pl \ - $(DTRACE2SYSTEMTAP_FLAGS) $(bindir) $(sbindir) $(libdir) $< > $@ + $(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(top_srcdir)/scripts/dtrace2systemtap.py \ + $(bindir) $(sbindir) $(libdir) $< > $@ CLEANFILES += libvirt_probes.h libvirt_probes.o libvirt_probes.lo \ libvirt_functions.stp libvirt_probes.stp @@ -761,9 +760,6 @@ endif LIBVIRT_INIT_SCRIPT_SYSTEMD endif WITH_LIBVIRTD -EXTRA_DIST += dtrace2systemtap.pl - - if WITH_LIBVIRTD libexec_PROGRAMS += libvirt_iohelper libvirt_iohelper_SOURCES = $(UTIL_IO_HELPER_SOURCES) diff --git a/src/dtrace2systemtap.pl b/src/dtrace2systemtap.pl deleted file mode 100755 index c5fce248b4..0000000000 --- a/src/dtrace2systemtap.pl +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env perl -# -# Copyright (C) 2011-2012 Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library. If not, see -# <http://www.gnu.org/licenses/>. -# -# -# Generate a set of systemtap probe definitions corresponding to -# DTrace probe markers in libvirt.so -# -# perl dtrace2systemtap.pl probes.d > libvirt_probes.stp -# - -use strict; -use warnings; - -my $file; -my @files; -my %files; - -my $with_modules = 0; -if ($ARGV[0] eq "--with-modules") { - # set if we want to honor the "module" setting in the .d file - $with_modules = 1; - shift @ARGV; -} - -my $bindir = shift @ARGV; -my $sbindir = shift @ARGV; -my $libdir = shift @ARGV; - -my $probe; -my $args; - -# Read the DTraceprobes definition -while (<>) { - next if m,^\s*$,; - - next if /^\s*provider\s+\w+\s*{\s*$/; - next if /^\s*};\s*$/; - - if (m,^\s*\#,) { - if (m,^\s*\#\s*file:\s*(\S+)\s*$,) { - $file = $1; - push @files, $file; - $files{$file} = { prefix => undef, probes => [] }; - } elsif (m,^\s*\#\s*prefix:\s*(\S+)\s*$,) { - $files{$file}->{prefix} = $1; - } elsif (m,^\s*\#\s*binary:\s*(\S+)\s*$,) { - $files{$file}->{binary} = $1; - } elsif (m,^\s*\#\s*module:\s*(\S+)\s*$,) { - $files{$file}->{module} = $1; - } else { - # ignore unknown comments - } - } else { - if (m,\s*probe\s+([a-zA-Z0-9_]+)\((.*?)(\);)?$,) { - $probe = $1; - $args = $2; - if ($3) { - push @{$files{$file}->{probes}}, [$probe, $args]; - $probe = $args = undef; - } - } elsif ($probe) { - if (m,^(.*?)(\);)?$,) { - $args .= $1; - if ($2) { - push @{$files{$file}->{probes}}, [$probe, $args]; - $probe = $args = undef; - } - } else { - die "unexpected data $_ on line $."; - } - } else { - die "unexpected data $_ on line $."; - } - } -} - -# Write out the SystemTap probes -foreach my $file (@files) { - my $prefix = $files{$file}->{prefix}; - my @probes = @{$files{$file}->{probes}}; - - print "# $file\n\n"; - foreach my $probe (@probes) { - my $name = $probe->[0]; - my $args = $probe->[1]; - - my $pname = $name; - $pname =~ s/${prefix}_/libvirt.$prefix./; - - my $binary = "$libdir/libvirt.so"; - if (exists $files{$file}->{binary}) { - $binary = $sbindir . "/" . $files{$file}->{binary}; - } - if ($with_modules && exists $files{$file}->{module}) { - $binary = $libdir . "/" . $files{$file}->{module}; - } - - print "probe $pname = process(\"$binary\").mark(\"$name\") {\n"; - - my @args = split /,/, $args; - for (my $i = 0 ; $i <= $#args ; $i++) { - my $arg = $args[$i]; - my $isstr = $arg =~ /char\s+\*/; - $arg =~ s/^.*\s\*?(\S+)$/$1/; - - if ($isstr) { - print " $arg = user_string(\$arg", $i + 1, ");\n"; - } else { - print " $arg = \$arg", $i + 1, ";\n"; - } - } - print "}\n\n"; - } - print "\n"; -} -- 2.21.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list