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(a)redhat.com>
---
src/Makefile.am | 9 ++-
src/dtrace2systemtap.pl | 130 ------------------------------------
src/dtrace2systemtap.py | 143 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 147 insertions(+), 135 deletions(-)
delete mode 100755 src/dtrace2systemtap.pl
create mode 100755 src/dtrace2systemtap.py
diff --git a/src/Makefile.am b/src/Makefile.am
index d10bfdf448..5a1df7a93c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -604,7 +604,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
@@ -639,10 +638,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 $(srcdir)/dtrace2systemtap.py \
$(top_builddir)/config.status
- $(AM_V_GEN)$(PERL) -w $(srcdir)/dtrace2systemtap.pl \
- $(DTRACE2SYSTEMTAP_FLAGS) $(bindir) $(sbindir) $(libdir) $< > $@
+ $(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(srcdir)/dtrace2systemtap.py \
+ $(bindir) $(sbindir) $(libdir) $< > $@
CLEANFILES += libvirt_probes.h libvirt_probes.o libvirt_probes.lo \
libvirt_functions.stp libvirt_probes.stp
@@ -763,7 +762,7 @@ endif LIBVIRT_INIT_SCRIPT_SYSTEMD
endif WITH_LIBVIRTD
-EXTRA_DIST += dtrace2systemtap.pl
+EXTRA_DIST += dtrace2systemtap.py
if WITH_LIBVIRTD
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";
-}
diff --git a/src/dtrace2systemtap.py b/src/dtrace2systemtap.py
new file mode 100755
index 0000000000..8ee5632d6b
--- /dev/null
+++ b/src/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.match(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.match(r'''^\#\s*prefix:\s*(\S+)$''', line)
+ if m is not None:
+ files[file]["prefix"] = m.group(1)
+ continue
+
+ m = re.match(r'''^\#\s*binary:\s*(\S+)$''', line)
+ if m is not None:
+ files[file]["binary"] = m.group(1)
+ continue
+
+ m = re.match(r'''^\#\s*module:\s*(\S+)$''', line)
+ if m is not None:
+ files[file]["module"] = m.group(1)
+
+ # ignore unknown comments
+ else:
+ m =
re.match(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.match(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.match(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("")
--
2.21.0