mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
src: rewrite systemtap probe generator in Python
As part of a 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. The "--with-modules" flag was dropped because this functionality is not implicitly always enabled. Tested-by: Cole Robinson <crobinso@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
d30a1ad044
commit
952c018efe
@ -50,6 +50,7 @@ EXTRA_DIST = \
|
|||||||
scripts/check-aclperms.py \
|
scripts/check-aclperms.py \
|
||||||
scripts/check-symfile.py \
|
scripts/check-symfile.py \
|
||||||
scripts/check-symsorting.py \
|
scripts/check-symsorting.py \
|
||||||
|
scripts/dtrace2systemtap.py \
|
||||||
scripts/header-ifdef.py \
|
scripts/header-ifdef.py \
|
||||||
scripts/minimize-po.py \
|
scripts/minimize-po.py \
|
||||||
scripts/mock-noinline.py \
|
scripts/mock-noinline.py \
|
||||||
|
143
scripts/dtrace2systemtap.py
Executable file
143
scripts/dtrace2systemtap.py
Executable file
@ -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("")
|
@ -527,7 +527,6 @@ if WITH_DTRACE_PROBES
|
|||||||
libvirt_la_BUILT_LIBADD += libvirt_probes.lo
|
libvirt_la_BUILT_LIBADD += libvirt_probes.lo
|
||||||
libvirt_la_DEPENDENCIES += libvirt_probes.lo libvirt_probes.o
|
libvirt_la_DEPENDENCIES += libvirt_probes.lo libvirt_probes.o
|
||||||
nodist_libvirt_la_SOURCES = libvirt_probes.h
|
nodist_libvirt_la_SOURCES = libvirt_probes.h
|
||||||
DTRACE2SYSTEMTAP_FLAGS = --with-modules
|
|
||||||
|
|
||||||
BUILT_SOURCES += libvirt_probes.h libvirt_probes.stp libvirt_functions.stp
|
BUILT_SOURCES += libvirt_probes.h libvirt_probes.stp libvirt_functions.stp
|
||||||
|
|
||||||
@ -562,10 +561,10 @@ RPC_PROBE_FILES += $(srcdir)/rpc/virnetprotocol.x \
|
|||||||
libvirt_functions.stp: $(RPC_PROBE_FILES) $(srcdir)/rpc/gensystemtap.pl
|
libvirt_functions.stp: $(RPC_PROBE_FILES) $(srcdir)/rpc/gensystemtap.pl
|
||||||
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gensystemtap.pl $(RPC_PROBE_FILES) > $@
|
$(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
|
$(top_builddir)/config.status
|
||||||
$(AM_V_GEN)$(PERL) -w $(srcdir)/dtrace2systemtap.pl \
|
$(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(top_srcdir)/scripts/dtrace2systemtap.py \
|
||||||
$(DTRACE2SYSTEMTAP_FLAGS) $(bindir) $(sbindir) $(libdir) $< > $@
|
$(bindir) $(sbindir) $(libdir) $< > $@
|
||||||
|
|
||||||
CLEANFILES += libvirt_probes.h libvirt_probes.o libvirt_probes.lo \
|
CLEANFILES += libvirt_probes.h libvirt_probes.o libvirt_probes.lo \
|
||||||
libvirt_functions.stp libvirt_probes.stp
|
libvirt_functions.stp libvirt_probes.stp
|
||||||
@ -686,9 +685,6 @@ endif LIBVIRT_INIT_SCRIPT_SYSTEMD
|
|||||||
endif WITH_LIBVIRTD
|
endif WITH_LIBVIRTD
|
||||||
|
|
||||||
|
|
||||||
EXTRA_DIST += dtrace2systemtap.pl
|
|
||||||
|
|
||||||
|
|
||||||
if WITH_LIBVIRTD
|
if WITH_LIBVIRTD
|
||||||
libexec_PROGRAMS += libvirt_iohelper
|
libexec_PROGRAMS += libvirt_iohelper
|
||||||
libvirt_iohelper_SOURCES = $(UTIL_IO_HELPER_SOURCES)
|
libvirt_iohelper_SOURCES = $(UTIL_IO_HELPER_SOURCES)
|
||||||
|
@ -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";
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user