exclude_file_name_regexp--sc_prohibit_setuid = ^src/util/util\.c$$
-exclude_file_name_regexp--sc_prohibit_sprintf = ^docs/hacking\.html\.in$$
+exclude_file_name_regexp--sc_prohibit_sprintf = \
+ ^(docs/hacking\.html\.in)|(src/dtrace2systemtap\.pl)|(src/rpc/gensystemtap\.pl)$$
exclude_file_name_regexp--sc_prohibit_strncpy = \
^(src/util/util|tools/virsh)\.c$$
THREADS.txt \
libvirtd.pod.in \
libvirtd.8.in \
- libvirtd.stp \
$(DAEMON_SOURCES)
BUILT_SOURCES =
$(SASL_LIBS) \
$(POLKIT_LIBS)
+if WITH_DTRACE
+libvirtd_LDADD += ../src/probes.o
+endif
+
libvirtd_LDADD += \
../src/libvirt-qemu.la
endif
endif
-if WITH_DTRACE
-libvirtd_LDADD += probes.o
-nodist_libvirtd_SOURCES = probes.h
-
-BUILT_SOURCES += probes.h
-
-tapsetdir = $(datadir)/systemtap/tapset
-tapset_DATA = libvirtd.stp
-
-probes.h: probes.d
- $(AM_V_GEN)$(DTRACE) -o $@ -h -s $<
-
-probes.o: probes.d
- $(AM_V_GEN)$(DTRACE) -o $@ -G -s $<
-
-CLEANFILES += probes.h probes.o
-endif
-
install-data-local: install-init install-data-sasl install-data-polkit \
install-logrotate
mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt
uninstall-local:: uninstall-data-sasl
endif # WITH_LIBVIRTD
-# This is needed for 'make dist' too, so can't wrap in WITH_LIBVIRTD.
-EXTRA_DIST += probes.d libvirtd.stp
-
POD2MAN = pod2man -c "Virtualization Support" \
-r "$(PACKAGE)-$(VERSION)" -s 8
# endif
# include "virnetserverprogram.h"
-# if WITH_DTRACE
-# ifndef LIBVIRTD_PROBES_H
-# define LIBVIRTD_PROBES_H
-# include "probes.h"
-# endif /* LIBVIRTD_PROBES_H */
-
-/* Systemtap 1.2 headers have a bug where they cannot handle a
- * variable declared with array type. Work around this by casting all
- * arguments. This is some gross use of the preprocessor because
- * PROBE is a var-arg macro, but it is better than the alternative of
- * making all callers to PROBE have to be aware of the issues. And
- * hopefully, if we ever add a call to PROBE with other than 2 or 3
- * end arguments, you can figure out the pattern to extend this hack.
- */
-# define VIR_COUNT_ARGS(...) VIR_ARG5(__VA_ARGS__, 4, 3, 2, 1)
-# define VIR_ARG5(_1, _2, _3, _4, _5, ...) _5
-# define VIR_ADD_CAST_EXPAND(a, b, ...) VIR_ADD_CAST_PASTE(a, b, __VA_ARGS__)
-# define VIR_ADD_CAST_PASTE(a, b, ...) a##b(__VA_ARGS__)
-
-/* The double cast is necessary to silence gcc warnings; any pointer
- * can safely go to intptr_t and back to void *, which collapses
- * arrays into pointers; while any integer can be widened to intptr_t
- * then cast to void *. */
-# define VIR_ADD_CAST(a) ((void *)(intptr_t)(a))
-# define VIR_ADD_CAST2(a, b) \
- VIR_ADD_CAST(a), VIR_ADD_CAST(b)
-# define VIR_ADD_CAST3(a, b, c) \
- VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c)
-
-# define VIR_ADD_CASTS(...) \
- VIR_ADD_CAST_EXPAND(VIR_ADD_CAST, VIR_COUNT_ARGS(__VA_ARGS__), \
- __VA_ARGS__)
-
-# define PROBE_EXPAND(NAME, ARGS) NAME(ARGS)
-# define PROBE(NAME, FMT, ...) \
- VIR_DEBUG_INT("trace." __FILE__ , __func__, __LINE__, \
- #NAME ": " FMT, __VA_ARGS__); \
- if (LIBVIRTD_ ## NAME ## _ENABLED()) { \
- PROBE_EXPAND(LIBVIRTD_ ## NAME, \
- VIR_ADD_CASTS(__VA_ARGS__)); \
- }
-# else
-# define PROBE(NAME, FMT, ...) \
- VIR_DEBUG_INT("trace." __FILE__, __func__, __LINE__, \
- #NAME ": " FMT, __VA_ARGS__);
-# endif
-
typedef struct daemonClientStream daemonClientStream;
typedef daemonClientStream *daemonClientStreamPtr;
typedef struct daemonClientPrivate daemonClientPrivate;
+++ /dev/null
-probe libvirt.daemon.client.connect = process("libvirtd").mark("client_connect")
-{
- fd = $arg1;
- readonly = $arg2;
- localAddr = user_string($arg3);
- remoteAddr = user_string($arg4);
-}
-
-probe libvirt.daemon.client.disconnect = process("libvirtd").mark("client_disconnect")
-{
- fd = $arg1;
-}
-
-
-probe libvirt.daemon.client.tls_allow = process("libvirtd").mark("client_tls_allow")
-{
- fd = $arg1;
- x509dname = user_string($arg2);
-}
-
-probe libvirt.daemon.client.tls_deny = process("libvirtd").mark("client_tls_deny")
-{
- fd = $arg1;
- x509dname = user_string($arg2);
-}
-
-probe libvirt.daemon.client.tls_fail = process("libvirtd").mark("client_tls_fail")
-{
- fd = $arg1;
-}
-
-
-function authtype_to_string(authtype) {
- if (authtype == 0)
- return "none"
- if (authtype == 1)
- return "sasl"
- if (authtype == 2)
- return "polkit"
- return "unknown"
-}
-
-
-probe libvirt.daemon.client.auth_allow = process("libvirtd").mark("client_auth_allow")
-{
- fd = $arg1;
- authtype = $arg2;
- authname = authtype_to_string($arg2);
- identity = user_string($arg3);
-}
-
-probe libvirt.daemon.client.auth_deny = process("libvirtd").mark("client_auth_deny")
-{
- fd = $arg1;
- authtype = $arg2;
- authname = authtype_to_string($arg2);
- identity = user_string($arg3);
-}
-
-probe libvirt.daemon.client.auth_fail = process("libvirtd").mark("client_auth_fail")
-{
- fd = $arg1;
- authtype = $arg2;
- authname = authtype_to_string($arg2);
-}
+++ /dev/null
-provider libvirtd {
- probe client_connect(int fd, int readonly, const char *localAddr, const char *remoteAddr);
- probe client_disconnect(int fd);
-
- probe client_auth_allow(int fd, int authtype, const char *identity);
- probe client_auth_deny(int fd, int authtype, const char *identity);
- probe client_auth_fail(int fd, int authtype);
-
- probe client_tls_allow(int fd, const char *x509dname);
- probe client_tls_deny(int fd, const char *x509dname);
- probe client_tls_fail(int fd);
-};
virNetError(VIR_ERR_AUTH_FAILED, "%s",
_("authentication failed"));
virNetMessageSaveError(rerr);
- PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d",
- virNetServerClientGetFD(client), REMOTE_AUTH_SASL);
+ PROBE(RPC_SERVER_CLIENT_AUTH_FAIL,
+ "client=%p auth=%d",
+ client, REMOTE_AUTH_SASL);
virNetSASLSessionFree(sasl);
virMutexUnlock(&priv->lock);
return -1;
VIR_DEBUG("Authentication successful %d", virNetServerClientGetFD(client));
identity = virNetSASLSessionGetIdentity(priv->sasl);
- PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
- virNetServerClientGetFD(client), REMOTE_AUTH_SASL, identity);
+ PROBE(RPC_SERVER_CLIENT_AUTH_ALLOW,
+ "client=%p auth=%d identity=%s",
+ client, REMOTE_AUTH_SASL, identity);
virNetSASLSessionFree(priv->sasl);
priv->sasl = NULL;
return 0;
authfail:
- PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d",
- virNetServerClientGetFD(client), REMOTE_AUTH_SASL);
+ PROBE(RPC_SERVER_CLIENT_AUTH_FAIL,
+ "client=%p auth=%d",
+ client, REMOTE_AUTH_SASL);
goto error;
authdeny:
identity = virNetSASLSessionGetIdentity(priv->sasl);
- PROBE(CLIENT_AUTH_DENY, "fd=%d, auth=%d, username=%s",
- virNetServerClientGetFD(client), REMOTE_AUTH_SASL, identity);
+ PROBE(RPC_SERVER_CLIENT_AUTH_DENY,
+ "client=%p auth=%d identity=%s",
+ client, REMOTE_AUTH_SASL, identity);
goto error;
error:
return 0;
authfail:
- PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d",
- virNetServerClientGetFD(client), REMOTE_AUTH_SASL);
+ PROBE(RPC_SERVER_CLIENT_AUTH_FAIL,
+ "client=%p auth=%d",
+ client, REMOTE_AUTH_SASL);
goto error;
authdeny:
identity = virNetSASLSessionGetIdentity(priv->sasl);
- PROBE(CLIENT_AUTH_DENY, "fd=%d, auth=%d, username=%s",
- virNetServerClientGetFD(client), REMOTE_AUTH_SASL, identity);
+ PROBE(RPC_SERVER_CLIENT_AUTH_DENY,
+ "client=%p auth=%d identity=%s",
+ client, REMOTE_AUTH_SASL, identity);
goto error;
error:
VIR_FREE(tmp);
goto authdeny;
}
- PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
- virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT, ident);
+ PROBE(RPC_SERVER_CLIENT_AUTH_ALLOW,
+ "client=%p auth=%d identity=%s",
+ client, REMOTE_AUTH_POLKIT, ident);
VIR_INFO("Policy allowed action %s from pid %d, uid %d",
action, callerPid, callerUid);
ret->complete = 1;
return -1;
authfail:
- PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d",
- virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT);
+ PROBE(RPC_SERVER_CLIENT_AUTH_FAIL,
+ "client=%p auth=%d",
+ client, REMOTE_AUTH_POLKIT);
goto error;
authdeny:
- PROBE(CLIENT_AUTH_DENY, "fd=%d, auth=%d, username=%s",
- virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT, (char *)ident);
+ PROBE(RPC_SERVER_CLIENT_AUTH_DENY,
+ "client=%p auth=%d identity=%s",
+ client, REMOTE_AUTH_POLKIT, (char *)ident);
goto error;
}
#elif HAVE_POLKIT0
polkit_result_to_string_representation(pkresult));
goto authdeny;
}
- PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
- virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT, ident);
+ PROBE(RPC_SERVER_CLIENT_AUTH_ALLOW,
+ "client=%p auth=%d identity=%s",
+ client, REMOTE_AUTH_POLKIT, ident);
VIR_INFO("Policy allowed action %s from pid %d, uid %d, result %s",
action, callerPid, callerUid,
polkit_result_to_string_representation(pkresult));
return -1;
authfail:
- PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d",
- virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT);
+ PROBE(RPC_SERVER_CLIENT_AUTH_FAIL,
+ "client=%p auth=%d",
+ client, REMOTE_AUTH_POLKIT);
goto error;
authdeny:
- PROBE(CLIENT_AUTH_DENY, "fd=%d, auth=%d, username=%s",
- virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT, ident);
+ PROBE(RPC_SERVER_CLIENT_AUTH_DENY,
+ "client=%p auth=%d identity=%s",
+ client, REMOTE_AUTH_POLKIT, ident);
goto error;
}
*.s
remote_protocol-structs-t
virt-aa-helper
+libvirt_functions.stp
+libvirt_probes.stp
+probes.o
+probes.h
EXTRA_DIST = $(conf_DATA) util/keymaps.csv
BUILT_SOURCES =
+CLEANFILES =
+DISTCLEANFILES =
+MAINTAINERCLEANFILES =
if WITH_NETWORK
UUID=$(shell uuidgen 2>/dev/null)
# picked out for us.
libvirt_la_DEPENDENCIES = $(libvirt_la_BUILT_LIBADD) $(LIBVIRT_SYMBOL_FILE)
+if WITH_DTRACE
+libvirt_la_LIBADD += probes.o
+nodist_libvirt_la_SOURCES = probes.h
+
+BUILT_SOURCES += probes.h libvirt_probes.stp libvirt_functions.stp
+
+tapsetdir = $(datadir)/systemtap/tapset
+tapset_DATA = libvirt_probes.stp libvirt_functions.stp
+
+probes.h: probes.d
+ $(AM_V_GEN)$(DTRACE) -o $@ -h -s $<
+
+probes.o: probes.d
+ $(AM_V_GEN)$(DTRACE) -o $@ -G -s $<
+
+RPC_PROBE_FILES = $(srcdir)/rpc/virnetprotocol.x $(srcdir)/remote/remote_protocol.x $(srcdir)/remote/qemu_protocol.x
+
+libvirt_functions.stp: $(RPC_PROBE_FILES) $(srcdir)/rpc/gensystemtap.pl
+ $(AM_V_GEN)perl -w $(srcdir)/rpc/gensystemtap.pl $(RPC_PROBE_FILES) > $@
+
+libvirt_probes.stp: probes.d $(srcdir)/dtrace2systemtap.pl
+ $(AM_V_GEN)perl -w $(srcdir)/dtrace2systemtap.pl $< > $@
+
+CLEANFILES += probes.h probes.o libvirt_functions.stp libvirt_probes.stp
+endif
+
+EXTRA_DIST += probes.d
+
+
# Create an automake "convenience library" version of libvirt_la,
# just for testing, since the test harness requires access to internal
# bits and pieces that we don't want to make publicly accessible.
$(LIBXML_LIBS) $(NUMACTL_LIBS) $(LIB_PTHREAD) \
$(LIBNL_LIBS) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) \
../gnulib/lib/libgnu.la
+if WITH_DTRACE
+libvirt_lxc_LDADD += probes.o
+endif
libvirt_lxc_CFLAGS = \
$(LIBPARTED_CFLAGS) \
$(NUMACTL_CFLAGS) \
endif
rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt" ||:
-CLEANFILES = *.gcov .libs/*.gcda .libs/*.gcno *.gcno *.gcda *.i *.s
-DISTCLEANFILES = $(GENERATED_SYM_FILES)
-MAINTAINERCLEANFILES = $(REMOTE_DRIVER_GENERATED) $(VIR_NET_RPC_GENERATED) $(ESX_DRIVER_GENERATED)
+CLEANFILES += *.gcov .libs/*.gcda .libs/*.gcno *.gcno *.gcda *.i *.s
+DISTCLEANFILES += $(GENERATED_SYM_FILES)
+MAINTAINERCLEANFILES += $(REMOTE_DRIVER_GENERATED) $(VIR_NET_RPC_GENERATED) $(ESX_DRIVER_GENERATED)
--- /dev/null
+#!/usr/bin/perl
+#
+# Copyright (C) 2011 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Author: Daniel P. Berrange <berrange@redhat.com>
+#
+# 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 $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*\#\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;
+ } 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./;
+
+ print "probe $pname = process(\"libvirt.so\").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";
+}
/* divide value by size, rounding up */
# define VIR_DIV_UP(value, size) (((value) + (size) - 1) / (size))
+
+# if WITH_DTRACE
+# ifndef LIBVIRT_PROBES_H
+# define LIBVIRT_PROBES_H
+# include "probes.h"
+# endif /* LIBVIRT_PROBES_H */
+
+/* Systemtap 1.2 headers have a bug where they cannot handle a
+ * variable declared with array type. Work around this by casting all
+ * arguments. This is some gross use of the preprocessor because
+ * PROBE is a var-arg macro, but it is better than the alternative of
+ * making all callers to PROBE have to be aware of the issues. And
+ * hopefully, if we ever add a call to PROBE with other than 9
+ * end arguments, you can figure out the pattern to extend this hack.
+ */
+# define VIR_COUNT_ARGS(...) VIR_ARG11(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
+# define VIR_ARG11(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) _11
+# define VIR_ADD_CAST_EXPAND(a, b, ...) VIR_ADD_CAST_PASTE(a, b, __VA_ARGS__)
+# define VIR_ADD_CAST_PASTE(a, b, ...) a##b(__VA_ARGS__)
+
+/* The double cast is necessary to silence gcc warnings; any pointer
+ * can safely go to intptr_t and back to void *, which collapses
+ * arrays into pointers; while any integer can be widened to intptr_t
+ * then cast to void *. */
+# define VIR_ADD_CAST(a) ((void *)(intptr_t)(a))
+# define VIR_ADD_CAST1(a) \
+ VIR_ADD_CAST(a)
+# define VIR_ADD_CAST2(a, b) \
+ VIR_ADD_CAST(a), VIR_ADD_CAST(b)
+# define VIR_ADD_CAST3(a, b, c) \
+ VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c)
+# define VIR_ADD_CAST4(a, b, c, d) \
+ VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
+ VIR_ADD_CAST(d)
+# define VIR_ADD_CAST5(a, b, c, d, e) \
+ VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
+ VIR_ADD_CAST(d), VIR_ADD_CAST(e)
+# define VIR_ADD_CAST6(a, b, c, d, e, f) \
+ VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
+ VIR_ADD_CAST(d), VIR_ADD_CAST(e), VIR_ADD_CAST(f)
+# define VIR_ADD_CAST7(a, b, c, d, e, f, g) \
+ VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
+ VIR_ADD_CAST(d), VIR_ADD_CAST(e), VIR_ADD_CAST(f), \
+ VIR_ADD_CAST(g)
+# define VIR_ADD_CAST8(a, b, c, d, e, f, g, h) \
+ VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
+ VIR_ADD_CAST(d), VIR_ADD_CAST(e), VIR_ADD_CAST(f), \
+ VIR_ADD_CAST(g), VIR_ADD_CAST(h)
+# define VIR_ADD_CAST9(a, b, c, d, e, f, g, h, i) \
+ VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c), \
+ VIR_ADD_CAST(d), VIR_ADD_CAST(e), VIR_ADD_CAST(f), \
+ VIR_ADD_CAST(g), VIR_ADD_CAST(h), VIR_ADD_CAST(i)
+
+# define VIR_ADD_CASTS(...) \
+ VIR_ADD_CAST_EXPAND(VIR_ADD_CAST, VIR_COUNT_ARGS(__VA_ARGS__), \
+ __VA_ARGS__)
+
+# define PROBE_EXPAND(NAME, ARGS) NAME(ARGS)
+# define PROBE(NAME, FMT, ...) \
+ VIR_DEBUG_INT("trace." __FILE__ , __func__, __LINE__, \
+ #NAME ": " FMT, __VA_ARGS__); \
+ if (LIBVIRT_ ## NAME ## _ENABLED()) { \
+ PROBE_EXPAND(LIBVIRT_ ## NAME, \
+ VIR_ADD_CASTS(__VA_ARGS__)); \
+ }
+# else
+# define PROBE(NAME, FMT, ...) \
+ VIR_DEBUG_INT("trace." __FILE__, __func__, __LINE__, \
+ #NAME ": " FMT, __VA_ARGS__);
+# endif
+
+
#endif /* __VIR_INTERNAL_H__ */
--- /dev/null
+provider libvirt {
+ # file: src/util/event_poll.c
+ # prefix: event_poll
+ probe event_poll_add_handle(int watch, int fd, int events, void *cb, void *opaque, void *ff);
+ probe event_poll_update_handle(int watch, int events);
+ probe event_poll_remove_handle(int watch);
+ probe event_poll_dispatch_handle(int watch, int events);
+ probe event_poll_purge_handle(int watch);
+
+ probe event_poll_add_timeout(int timer, int frequency, void *cb, void *opaque, void *ff);
+ probe event_poll_update_timeout(int timer, int frequency);
+ probe event_poll_remove_timeout(int timer);
+ probe event_poll_dispatch_timeout(int timer);
+ probe event_poll_purge_timeout(int timer);
+
+ probe event_poll_run(int nfds, int timeout);
+
+
+ # file: src/rpc/virnetsocket.c
+ # prefix: rpc
+ probe rpc_socket_new(void *sock, int refs, int fd, int errfd, int pid, const char *localAddr, const char *remoteAddr);
+ probe rpc_socket_ref(void *sock, int refs);
+ probe rpc_socket_free(void *sock, int refs);
+
+
+ # file: src/rpc/virnetserverclient.c
+ # prefix: rpc
+ probe rpc_server_client_new(void *client, int refs, void *sock);
+ probe rpc_server_client_ref(void *client, int refs);
+ probe rpc_server_client_free(void *client, int refs);
+
+ probe rpc_server_client_msg_tx_queue(void *client, int len, int prog, int vers, int proc, int type, int status, int serial);
+ probe rpc_server_client_msg_rx(void *client, int len, int prog, int vers, int proc, int type, int status, int serial);
+
+
+ # file: src/rpc/virnetclient.c
+ # prefix: rpc
+ probe rpc_client_new(void *client, int refs, void *sock);
+ probe rpc_client_ref(void *client, int refs);
+ probe rpc_client_free(void *client, int refs);
+
+ probe rpc_client_msg_tx_queue(void *client, int len, int prog, int vers, int proc, int type, int status, int serial);
+ probe rpc_client_msg_rx(void *client, int len, int prog, int vers, int proc, int type, int status, int serial);
+
+
+ # file: daemon/libvirtd.c
+ # prefix: rpc
+ probe rpc_server_client_auth_allow(void *client, int authtype, const char *identity);
+ probe rpc_server_client_auth_deny(void *client, int authtype, const char *identity);
+ probe rpc_server_client_auth_fail(void *client, int authtype);
+
+
+ # file: src/rpc/virnettlscontext.c
+ # prefix: rpc
+ probe rpc_tls_context_new(void *ctxt, int refs, const char *cacert, const char *cacrl,
+ const char *cert, const char *key, int sanityCheckCert, int requireValidCert, int isServer);
+ probe rpc_tls_context_ref(void *ctxt, int refs);
+ probe rpc_tls_context_free(void *ctxt, int refs);
+
+ probe rpc_tls_context_session_allow(void *ctxt, void *sess, const char *dname);
+ probe rpc_tls_context_session_deny(void *ctxt, void *sess, const char *dname);
+ probe rpc_tls_context_session_fail(void *ctxt, void *sess);
+
+
+ probe rpc_tls_session_new(void *sess, void *ctxt, int refs, const char *hostname, int isServer);
+ probe rpc_tls_session_ref(void *sess, int refs);
+ probe rpc_tls_session_free(void *sess, int refs);
+
+ probe rpc_tls_session_handshake_pass(void *sess);
+ probe rpc_tls_session_handshake_fail(void *sess);
+
+};
--- /dev/null
+#!/usr/bin/perl
+#
+# Copyright (C) 2011 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Author: Daniel P. Berrange <berrange@redhat.com>
+#
+# Generate a set of systemtap functions for translating various
+# RPC enum values into strings
+#
+# perl gensystemtap.pl */*.x > libvirt_functions.stp
+#
+
+use strict;
+
+my %funcs;
+
+my %type;
+my %status;
+my %auth;
+
+my $instatus = 0;
+my $intype = 0;
+my $inauth = 0;
+while (<>) {
+ if (/enum\s+virNetMessageType/) {
+ $intype = 1;
+ } elsif (/enum\s+virNetMessageStatus/) {
+ $instatus = 1;
+ } elsif (/enum remote_auth_type/) {
+ $inauth = 1;
+ } elsif (/}/) {
+ $instatus = $intype = $inauth = 0;
+ } elsif ($instatus) {
+ if (/^\s+VIR_NET_(\w+)\s*=\s*(\d+),?$/) {
+ $status{$2} = lc $1;
+ }
+ } elsif ($intype) {
+ if (/^\s+VIR_NET_(\w+)\s*=\s*(\d+),?$/) {
+ $type{$2} = lc $1;
+ }
+ } elsif ($inauth) {
+ if (/^\s+REMOTE_AUTH_(\w+)\s*=\s*(\d+),?$/) {
+ $auth{$2} = lc $1;
+ }
+ } else {
+ if (/(\w+)_PROGRAM\s*=\s*0x([a-fA-F0-9]+)\s*;/) {
+ $funcs{lc $1} = { id => hex($2), version => undef, progs => [] };
+ } elsif (/(\w+)_PROTOCOL_VERSION\s*=\s*(\d+)\s*;/) {
+ $funcs{lc $1}->{version} = $2;
+ } elsif (/(\w+)_PROC_(.*?)\s+=\s+(\d+)/) {
+ $funcs{lc $1}->{progs}->[$3] = lc $2;
+ }
+ }
+}
+
+print <<EOF;
+function libvirt_rpc_auth_name(type, verbose)
+{
+EOF
+my $first = 1;
+foreach my $type (keys %auth) {
+ my $cond = $first ? "if" : "} else if";
+ $first = 0;
+ print " $cond (type == ", $type, ") {\n";
+ print " typestr = \"", $auth{$type}, "\"\n";
+}
+print <<EOF;
+ } else {
+ typestr = "unknown";
+ verbose = 1;
+ }
+ if (verbose) {
+ typestr = typestr . sprintf(":%d", type)
+ }
+ return typestr;
+}
+EOF
+
+print <<EOF;
+function libvirt_rpc_type_name(type, verbose)
+{
+EOF
+$first = 1;
+foreach my $type (keys %type) {
+ my $cond = $first ? "if" : "} else if";
+ $first = 0;
+ print " $cond (type == ", $type, ") {\n";
+ print " typestr = \"", $type{$type}, "\"\n";
+}
+print <<EOF;
+ } else {
+ typestr = "unknown";
+ verbose = 1;
+ }
+ if (verbose) {
+ typestr = typestr . sprintf(":%d", type)
+ }
+ return typestr;
+}
+EOF
+
+print <<EOF;
+function libvirt_rpc_status_name(status, verbose)
+{
+EOF
+$first = 1;
+foreach my $status (keys %status) {
+ my $cond = $first ? "if" : "} else if";
+ $first = 0;
+ print " $cond (status == ", $status, ") {\n";
+ print " statusstr = \"", $status{$status}, "\"\n";
+}
+print <<EOF;
+ } else {
+ statusstr = "unknown";
+ verbose = 1;
+ }
+ if (verbose) {
+ statusstr = statusstr . sprintf(":%d", status)
+ }
+ return statusstr;
+}
+EOF
+
+print <<EOF;
+function libvirt_rpc_program_name(program, verbose)
+{
+EOF
+$first = 1;
+foreach my $prog (keys %funcs) {
+ my $cond = $first ? "if" : "} else if";
+ $first = 0;
+ print " $cond (program == ", $funcs{$prog}->{id}, ") {\n";
+ print " programstr = \"", $prog, "\"\n";
+}
+print <<EOF;
+ } else {
+ programstr = "unknown";
+ verbose = 1;
+ }
+ if (verbose) {
+ programstr = programstr . sprintf(":%d", program)
+ }
+ return programstr;
+}
+EOF
+
+
+print <<EOF;
+function libvirt_rpc_procedure_name(program, version, proc, verbose)
+{
+EOF
+$first = 1;
+foreach my $prog (keys %funcs) {
+ my $cond = $first ? "if" : "} else if";
+ $first = 0;
+ print " $cond (program == ", $funcs{$prog}->{id}, " && version == ", $funcs{$prog}->{version}, ") {\n";
+
+ my $pfirst = 1;
+ for (my $id = 1 ; $id <= $#{$funcs{$prog}->{progs}} ; $id++) {
+ my $cond = $pfirst ? "if" : "} else if";
+ $pfirst = 0;
+ print " $cond (proc == $id) {\n";
+ print " procstr = \"", $funcs{$prog}->{progs}->[$id], "\";\n";
+ }
+ print " } else {\n";
+ print " procstr = \"unknown\";\n";
+ print " verbose = 1;\n";
+ print " }\n";
+}
+print <<EOF;
+ } else {
+ procstr = "unknown";
+ verbose = 1;
+ }
+ if (verbose) {
+ procstr = procstr . sprintf(":%d", proc)
+ }
+ return procstr;
+}
+EOF
VIR_DEBUG("Failed to add event watch, disabling events");
}
- VIR_DEBUG("client=%p refs=%d", client, client->refs);
+ PROBE(RPC_CLIENT_NEW,
+ "client=%p refs=%d sock=%p",
+ client, client->refs, client->sock);
+
return client;
no_memory:
{
virNetClientLock(client);
client->refs++;
- VIR_DEBUG("client=%p refs=%d", client, client->refs);
+ PROBE(RPC_CLIENT_REF,
+ "client=%p refs=%d",
+ client, client->refs);
virNetClientUnlock(client);
}
return;
virNetClientLock(client);
- VIR_DEBUG("client=%p refs=%d", client, client->refs);
+ PROBE(RPC_CLIENT_FREE,
+ "client=%p refs=%d",
+ client, client->refs);
client->refs--;
if (client->refs > 0) {
virNetClientUnlock(client);
if (virNetMessageDecodeHeader(&client->msg) < 0)
return -1;
- VIR_DEBUG("Incoming message prog %d vers %d proc %d type %d status %d serial %d",
- client->msg.header.prog, client->msg.header.vers,
- client->msg.header.proc, client->msg.header.type,
- client->msg.header.status, client->msg.header.serial);
+ PROBE(RPC_CLIENT_MSG_RX,
+ "client=%p len=%zu prog=%u vers=%u proc=%u type=%u status=%u serial=%u",
+ client, client->msg.bufferLength,
+ client->msg.header.prog, client->msg.header.vers, client->msg.header.proc,
+ client->msg.header.type, client->msg.header.status, client->msg.header.serial);
switch (client->msg.header.type) {
case VIR_NET_REPLY: /* Normal RPC replies */
virNetClientCallPtr call;
int ret = -1;
+ PROBE(RPC_CLIENT_MSG_TX_QUEUE,
+ "client=%p len=%zu prog=%u vers=%u proc=%u type=%u status=%u serial=%u",
+ client, msg->bufferLength,
+ msg->header.prog, msg->header.vers, msg->header.proc,
+ msg->header.type, msg->header.status, msg->header.serial);
+
if (expectReply &&
(msg->bufferLength != 0) &&
(msg->header.status == VIR_NET_CONTINUE)) {
client->rx->bufferLength = VIR_NET_MESSAGE_LEN_MAX;
client->nrequests = 1;
- VIR_DEBUG("client=%p refs=%d", client, client->refs);
+ PROBE(RPC_SERVER_CLIENT_NEW,
+ "client=%p refs=%d sock=%p",
+ client, client->refs, client->sock);
return client;
{
virNetServerClientLock(client);
client->refs++;
- VIR_DEBUG("client=%p refs=%d", client, client->refs);
+ PROBE(RPC_SERVER_CLIENT_REF,
+ "client=%p refs=%d",
+ client, client->refs);
virNetServerClientUnlock(client);
}
return;
virNetServerClientLock(client);
- VIR_DEBUG("client=%p refs=%d", client, client->refs);
+ PROBE(RPC_SERVER_CLIENT_FREE,
+ "client=%p refs=%d",
+ client, client->refs);
client->refs--;
if (client->refs > 0) {
return;
}
+ PROBE(RPC_SERVER_CLIENT_MSG_RX,
+ "client=%p len=%zu prog=%u vers=%u proc=%u type=%u status=%u serial=%u",
+ client, msg->bufferLength,
+ msg->header.prog, msg->header.vers, msg->header.proc,
+ msg->header.type, msg->header.status, msg->header.serial);
+
/* Maybe send off for queue against a filter */
filter = client->filters;
while (filter) {
virNetServerClientLock(client);
if (client->sock && !client->wantClose) {
+ PROBE(RPC_SERVER_CLIENT_MSG_TX_QUEUE,
+ "client=%p len=%zu prog=%u vers=%u proc=%u type=%u status=%u serial=%u",
+ client, msg->bufferLength,
+ msg->header.prog, msg->header.vers, msg->header.proc,
+ msg->header.type, msg->header.status, msg->header.serial);
virNetMessageQueuePush(&client->tx, msg);
virNetServerClientUpdateEvent(client);
sock->client = isClient;
- VIR_DEBUG("sock=%p localAddrStr=%s remoteAddrStr=%s",
- sock, NULLSTR(sock->localAddrStr), NULLSTR(sock->remoteAddrStr));
+ PROBE(RPC_SOCKET_NEW,
+ "sock=%p refs=%d fd=%d errfd=%d pid=%d localAddr=%s, remoteAddr=%s",
+ sock, sock->refs, fd, errfd,
+ pid, NULLSTR(sock->localAddrStr), NULLSTR(sock->remoteAddrStr));
return sock;
{
virMutexLock(&sock->lock);
sock->refs++;
+ PROBE(RPC_SOCKET_REF,
+ "sock=%p refs=%d",
+ sock, sock->refs);
virMutexUnlock(&sock->lock);
}
return;
virMutexLock(&sock->lock);
+ PROBE(RPC_SOCKET_FREE,
+ "sock=%p refs=%d",
+ sock, sock->refs);
+
sock->refs--;
if (sock->refs > 0) {
virMutexUnlock(&sock->lock);
char *gnutlsdebug;
int err;
- VIR_DEBUG("cacert=%s cacrl=%s cert=%s key=%s sanityCheckCert=%d requireValid=%d isServer=%d",
- cacert, NULLSTR(cacrl), cert, key, sanityCheckCert, requireValidCert, isServer);
-
if (VIR_ALLOC(ctxt) < 0) {
virReportOOMError();
return NULL;
ctxt->x509dnWhitelist = x509dnWhitelist;
ctxt->isServer = isServer;
+ PROBE(RPC_TLS_CONTEXT_NEW,
+ "ctxt=%p refs=%d cacert=%s cacrl=%s cert=%s key=%s sanityCheckCert=%d requireValidCert=%d isServer=%d",
+ ctxt, ctxt->refs, cacert, NULLSTR(cacrl), cert, key, sanityCheckCert, requireValidCert, isServer);
+
return ctxt;
error:
{
virMutexLock(&ctxt->lock);
ctxt->refs++;
+ PROBE(RPC_TLS_CONTEXT_REF,
+ "ctxt=%p refs=%d",
+ ctxt, ctxt->refs);
virMutexUnlock(&ctxt->lock);
}
gnutls_x509_crt_deinit(cert);
}
-#if 0
- PROBE(CLIENT_TLS_ALLOW, "fd=%d, name=%s",
- virNetServerClientGetFD(client), name);
-#endif
+ PROBE(RPC_TLS_CONTEXT_SESSION_ALLOW,
+ "ctxt=%p sess=%p dname=%s",
+ ctxt, sess, dname);
+
return 0;
authdeny:
-#if 0
- PROBE(CLIENT_TLS_DENY, "fd=%d, name=%s",
- virNetServerClientGetFD(client), name);
-#endif
+ PROBE(RPC_TLS_CONTEXT_SESSION_DENY,
+ "ctxt=%p sess=%p dname=%s",
+ ctxt, sess, dname);
+
return -1;
authfail:
-#if 0
- PROBE(CLIENT_TLS_FAIL, "fd=%d",
- virNetServerClientGetFD(client));
-#endif
+ PROBE(RPC_TLS_CONTEXT_SESSION_FAIL,
+ "ctxt=%p sess=%p",
+ ctxt, sess);
+
return -1;
}
return;
virMutexLock(&ctxt->lock);
+ PROBE(RPC_TLS_CONTEXT_FREE,
+ "ctxt=%p refs=%d",
+ ctxt, ctxt->refs);
ctxt->refs--;
if (ctxt->refs > 0) {
virMutexUnlock(&ctxt->lock);
sess->isServer = ctxt->isServer;
+ PROBE(RPC_TLS_SESSION_NEW,
+ "sess=%p refs=%d ctxt=%p hostname=%s isServer=%d",
+ sess, sess->refs, ctxt, hostname, sess->isServer);
+
return sess;
error:
{
virMutexLock(&sess->lock);
sess->refs++;
+ PROBE(RPC_TLS_SESSION_REF,
+ "sess=%p refs=%d",
+ sess, sess->refs);
virMutexUnlock(&sess->lock);
}
return;
virMutexLock(&sess->lock);
+ PROBE(RPC_TLS_SESSION_FREE,
+ "sess=%p refs=%d",
+ sess, sess->refs);
sess->refs--;
if (sess->refs > 0) {
virMutexUnlock(&sess->lock);
void *opaque,
virFreeCallback ff) {
int watch;
- EVENT_DEBUG("Add handle fd=%d events=%d cb=%p opaque=%p", fd, events, cb, opaque);
virMutexLock(&eventLoop.lock);
if (eventLoop.handlesCount == eventLoop.handlesAlloc) {
EVENT_DEBUG("Used %zu handle slots, adding at least %d more",
eventLoop.handlesCount++;
virEventPollInterruptLocked();
+
+ PROBE(EVENT_POLL_ADD_HANDLE,
+ "watch=%d fd=%d events=%d cb=%p opaque=%p ff=%p",
+ watch, fd, events, cb, opaque, ff);
virMutexUnlock(&eventLoop.lock);
return watch;
void virEventPollUpdateHandle(int watch, int events) {
int i;
- EVENT_DEBUG("Update handle w=%d e=%d", watch, events);
+ PROBE(EVENT_POLL_UPDATE_HANDLE,
+ "watch=%d events=%d",
+ watch, events);
if (watch <= 0) {
VIR_WARN("Ignoring invalid update watch %d", watch);
*/
int virEventPollRemoveHandle(int watch) {
int i;
- EVENT_DEBUG("Remove handle w=%d", watch);
+ PROBE(EVENT_POLL_REMOVE_HANDLE,
+ "watch=%d",
+ watch);
if (watch <= 0) {
VIR_WARN("Ignoring invalid remove watch %d", watch);
{
unsigned long long now;
int ret;
- EVENT_DEBUG("Adding timer %d with %d ms freq", nextTimer, frequency);
+
if (virTimeMs(&now) < 0) {
return -1;
}
eventLoop.timeoutsCount++;
ret = nextTimer-1;
virEventPollInterruptLocked();
+
+ PROBE(EVENT_POLL_ADD_TIMEOUT,
+ "timer=%d frequency=%d cb=%p opaque=%p ff=%p",
+ ret, frequency, cb, opaque, ff);
virMutexUnlock(&eventLoop.lock);
return ret;
}
{
unsigned long long now;
int i;
- EVENT_DEBUG("Updating timer %d timeout with %d ms freq", timer, frequency);
+ PROBE(EVENT_POLL_UPDATE_TIMEOUT,
+ "timer=%d frequency=%d",
+ timer, frequency);
if (timer <= 0) {
VIR_WARN("Ignoring invalid update timer %d", timer);
*/
int virEventPollRemoveTimeout(int timer) {
int i;
- EVENT_DEBUG("Remove timer %d", timer);
+ PROBE(EVENT_POLL_REMOVE_TIMEOUT,
+ "timer=%d",
+ timer);
if (timer <= 0) {
VIR_WARN("Ignoring invalid remove timer %d", timer);
eventLoop.timeouts[i].expiresAt =
now + eventLoop.timeouts[i].frequency;
+ PROBE(EVENT_POLL_DISPATCH_TIMEOUT,
+ "timer=%d",
+ timer);
virMutexUnlock(&eventLoop.lock);
(cb)(timer, opaque);
virMutexLock(&eventLoop.lock);
int watch = eventLoop.handles[i].watch;
void *opaque = eventLoop.handles[i].opaque;
int hEvents = virEventPollFromNativeEvents(fds[n].revents);
- EVENT_DEBUG("Dispatch n=%d f=%d w=%d e=%d %p", i,
- fds[n].fd, watch, fds[n].revents, opaque);
+ PROBE(EVENT_POLL_DISPATCH_HANDLE,
+ "watch=%d events=%d",
+ watch, hEvents);
virMutexUnlock(&eventLoop.lock);
(cb)(watch, fds[n].fd, hEvents, opaque);
virMutexLock(&eventLoop.lock);
continue;
}
- EVENT_DEBUG("Purging timeout %d with id %d", i,
- eventLoop.timeouts[i].timer);
+ PROBE(EVENT_POLL_PURGE_TIMEOUT,
+ "timer=%d",
+ eventLoop.timeouts[i].timer);
if (eventLoop.timeouts[i].ff) {
virFreeCallback ff = eventLoop.timeouts[i].ff;
void *opaque = eventLoop.timeouts[i].opaque;
continue;
}
+ PROBE(EVENT_POLL_PURGE_HANDLE,
+ "watch=%d",
+ eventLoop.handles[i].watch);
if (eventLoop.handles[i].ff) {
virFreeCallback ff = eventLoop.handles[i].ff;
void *opaque = eventLoop.handles[i].opaque;
virMutexUnlock(&eventLoop.lock);
retry:
- EVENT_DEBUG("Poll on %d handles %p timeout %d", nfds, fds, timeout);
+ PROBE(EVENT_POLL_RUN,
+ "nhandles=%d imeout=%d",
+ nfds, timeout);
ret = poll(fds, nfds, timeout);
if (ret < 0) {
EVENT_DEBUG("Poll got error event %d", errno);