SUBDIRS = gnulib/lib include src daemon tools proxy docs gnulib/tests \
python tests po examples/domain-events/events-c examples/hellolibvirt \
examples/dominfo examples/domsuspend examples/python examples/apparmor \
- examples/xml/nwfilter examples/openauth
+ examples/xml/nwfilter examples/openauth examples/systemtap
ACLOCAL_AMFLAGS = -I m4 -I gnulib/m4
--without-phyp \
--without-netcf \
--without-audit \
+ --without-dtrace \
--without-libvirtd
make
AM_CONDITIONAL([WITH_SECDRIVER_APPARMOR], [test "$with_secdriver_apparmor" != "no"])
+dnl DTrace static probes
+AC_ARG_WITH([dtrace],
+ AC_HELP_STRING([--with-dtrace], [use dtrace for static probing @<:@default=check@:>@]),
+ [],
+ [with_dtrace=check])
+
+if test "$with_dtrace" != "no" ; then
+ AC_PATH_PROG([DTRACE], [dtrace], [], [/bin:/usr/bin])
+ if test -z "$DTRACE" ; then
+ if test "$with_dtrace" = "check"; then
+ with_dtrace=no
+ else
+ AC_MSG_ERROR([You must install the 'dtrace' binary to enable libvirt static probes])
+ fi
+ else
+ with_dtrace=yes
+ fi
+ if test "$with_dtrace" = "yes"; then
+ AC_DEFINE_UNQUOTED([WITH_DTRACE], 1, [whether DTrace static probes are available])
+ fi
+fi
+AM_CONDITIONAL([WITH_DTRACE], [test "$with_dtrace" != "no"])
+
dnl NUMA lib
AC_ARG_WITH([numactl],
examples/openauth/Makefile \
examples/python/Makefile \
examples/hellolibvirt/Makefile \
+ examples/systemtap/Makefile \
examples/xml/nwfilter/Makefile)
AC_MSG_NOTICE([])
AC_MSG_NOTICE([ Warnings: $enable_compile_warnings])
AC_MSG_NOTICE([ Readline: $lv_use_readline])
AC_MSG_NOTICE([ Python: $with_python])
+AC_MSG_NOTICE([ DTrace: $with_dtrace])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Privileges])
AC_MSG_NOTICE([])
libvirtd*.logrotate
libvirtd.pod
libvirtd.8
+probes.h
## Process this file with automake to produce Makefile.in
+CLEANFILES =
+
DAEMON_SOURCES = \
event.c event.h \
libvirtd.c libvirtd.h \
test_libvirtd.aug \
THREADING.txt \
libvirtd.pod.in \
+ libvirtd.stp \
$(AVAHI_SOURCES) \
$(DAEMON_SOURCES)
libvirtd_LDADD += $(AVAHI_LIBS)
endif
+EXTRA_DIST += probes.d libvirtd.stp
+
+if WITH_DTRACE
+libvirtd_LDADD += probes.o
+libvirtd_SOURCES += probes.h
+
+BUILT_SOURCES += probes.h
+
+tapsetdir = $(datadir)/systemtap/tapsets
+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
endif
-CLEANFILES = $(BUILT_SOURCES) $(man_MANS) libvirtd.pod
+CLEANFILES += $(BUILT_SOURCES) $(man_MANS) libvirtd.pod
CLEANFILES += *.cov *.gcov .libs/*.gcda .libs/*.gcno *.gcno *.gcda
}
}
+ PROBE(CLIENT_TLS_ALLOW, "fd=%d, name=%s", client->fd, name);
return 0;
authdeny:
+ PROBE(CLIENT_TLS_DENY, "fd=%d, name=%s", client->fd, name);
return -1;
authfail:
+ PROBE(CLIENT_TLS_FAIL, "fd=%d", client->fd);
return -1;
}
return -1;
}
+ PROBE(CLIENT_CONNECT, "fd=%d, readonly=%d", fd, sock->readonly);
+
if (server->nclients >= max_clients) {
VIR_ERROR(_("Too many active clients (%d), dropping connection"), max_clients);
goto error;
if (qemudRegisterClientEvent (server, client) < 0)
goto error;
} else {
+ PROBE(CLIENT_TLS_FAIL, "fd=%d", client->fd);
VIR_ERROR(_("TLS handshake failed: %s"),
gnutls_strerror (ret));
goto error;
VIR_FREE(client);
}
close (fd);
+ PROBE(CLIENT_DISCONNECT, "fd=%d", fd);
return -1;
}
client->tlssession = NULL;
}
if (client->fd != -1) {
+ PROBE(CLIENT_DISCONNECT, "fd=%d", client->fd);
close(client->fd);
client->fd = -1;
}
direction has changed */
qemudUpdateClientEvent (client);
} else {
+ PROBE(CLIENT_TLS_FAIL, "fd=%d", client->fd);
/* Fatal error in handshake */
VIR_ERROR(_("TLS handshake failed: %s"),
gnutls_strerror (ret));
# include "logging.h"
# include "threads.h"
+# if WITH_DTRACE
+# ifndef LIBVIRTD_PROBES_H
+# define LIBVIRTD_PROBES_H
+# include "probes.h"
+# endif /* LIBVIRTD_PROBES_H */
+# define PROBE(NAME, FMT, ...) \
+ VIR_DEBUG_INT("trace." __FILE__ , __func__, __LINE__, \
+ #NAME ": " FMT, __VA_ARGS__); \
+ if (LIBVIRTD_ ## NAME ## _ENABLED()) { \
+ LIBVIRTD_ ## NAME(__VA_ARGS__); \
+ }
+# else
+# define PROBE(NAME, FMT, ...) \
+ VIR_DEBUG_INT("trace." __FILE__, __func__, __LINE__, \
+ #NAME ": " FMT, __VA_ARGS__);
+# endif
+
# ifdef __GNUC__
# ifdef HAVE_ANSIDECL_H
# include <ansidecl.h>
--- /dev/null
+probe libvirt.daemon.client.connect = process("libvirtd").mark("client_connect")
+{
+ fd = $arg1;
+ readonly = $arg2;
+}
+
+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);
+ 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);
+};
authfail:
remoteDispatchAuthError(rerr);
error:
+ PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
virMutexUnlock(&client->lock);
return -1;
}
}
REMOTE_DEBUG("Authentication successful %d", client->fd);
+ PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
+ client->fd, REMOTE_AUTH_SASL, client->saslUsername);
ret->complete = 1;
client->auth = REMOTE_AUTH_NONE;
}
return 0;
authfail:
+ PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
remoteDispatchAuthError(rerr);
goto error;
authdeny:
+ PROBE(CLIENT_AUTH_DENY, "fd=%d, auth=%d, username=%s",
+ client->fd, REMOTE_AUTH_SASL, client->saslUsername);
goto error;
error:
}
REMOTE_DEBUG("Authentication successful %d", client->fd);
+ PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
+ client->fd, REMOTE_AUTH_SASL, client->saslUsername);
ret->complete = 1;
client->auth = REMOTE_AUTH_NONE;
}
return 0;
authfail:
+ PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
remoteDispatchAuthError(rerr);
goto error;
authdeny:
+ PROBE(CLIENT_AUTH_DENY, "fd=%d, auth=%d, username=%s",
+ client->fd, REMOTE_AUTH_SASL, client->saslUsername);
goto error;
error:
remote_auth_sasl_init_ret *ret ATTRIBUTE_UNUSED)
{
VIR_ERROR0(_("client tried unsupported SASL init request"));
+ PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
remoteDispatchAuthError(rerr);
return -1;
}
remote_auth_sasl_start_ret *ret ATTRIBUTE_UNUSED)
{
VIR_ERROR0(_("client tried unsupported SASL start request"));
+ PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
remoteDispatchAuthError(rerr);
return -1;
}
remote_auth_sasl_step_ret *ret ATTRIBUTE_UNUSED)
{
VIR_ERROR0(_("client tried unsupported SASL step request"));
+ PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
remoteDispatchAuthError(rerr);
return -1;
}
action, callerPid, callerUid, status);
goto authdeny;
}
+ PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
+ client->fd, REMOTE_AUTH_POLKIT, ident);
VIR_INFO(_("Policy allowed action %s from pid %d, uid %d"),
action, callerPid, callerUid);
ret->complete = 1;
return 0;
authfail:
+ PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_POLKIT);
goto error;
authdeny:
+ PROBE(CLIENT_AUTH_DENY, "fd=%d, auth=%d, username=%s",
+ client->fd, REMOTE_AUTH_POLKIT, ident);
goto error;
error:
polkit_result_to_string_representation(pkresult));
goto authdeny;
}
+ PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
+ client->fd, 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 0;
authfail:
+ PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_POLKIT);
goto error;
authdeny:
+ PROBE(CLIENT_AUTH_DENY, "fd=%d, auth=%d, username=%s",
+ client->fd, REMOTE_AUTH_POLKIT, ident);
goto error;
error:
--- /dev/null
+
+EXTRA_DIST = client.stp
--- /dev/null
+#!/usr/bin/stap
+
+probe libvirt.daemon.client.connect {
+ printf("Client fd=%d connected readonly=%d\n", fd, readonly);
+}
+probe libvirt.daemon.client.disconnect {
+ printf("Client fd=%d disconnected\n", fd);
+}
+
+probe libvirt.daemon.client.tls_allow {
+ printf("Client fd=%d tls allow %s\n", fd, x509dname);
+}
+probe libvirt.daemon.client.tls_deny {
+ printf("Client fd=%d tls deny %s\n", fd, x509dname);
+}
+probe libvirt.daemon.client.tls_fail {
+ printf("Client fd=%d tls fail\n", fd);
+}
+
+probe libvirt.daemon.client.auth_allow {
+ printf("Client fd=%d auth %s allow %s\n", fd, authname, identity);
+}
+probe libvirt.daemon.client.auth_deny {
+ printf("Client fd=%d auth %s deny %s\n", fd, authname, identity);
+}
+probe libvirt.daemon.client.auth_fail {
+ printf("Client fd=%d auth %s fail\n", fd, authname);
+}
%define with_macvtap 0%{!?_without_macvtap:0}
%define with_libnl 0%{!?_without_libnl:0}
%define with_audit 0%{!?_without_audit:0}
+%define with_dtrace 0%{!?_without_dtrace:0}
# Non-server/HV driver defaults which are always enabled
%define with_python 0%{!?_without_python:1}
%define with_audit 0%{!?_without_audit:1}
%endif
+%if 0%{?fedora} >= 13 || 0%{?rhel} >= 6
+%define with_dtrace 1
+%endif
+
# Force QEMU to run as non-root
%if 0%{?fedora} >= 12 || 0%{?rhel} >= 6
%define qemu_user qemu
%define _without_audit --without-audit
%endif
+%if ! %{with_dtrace}
+%define _without_dtrace --without-dtrace
+%endif
+
%configure %{?_without_xen} \
%{?_without_qemu} \
%{?_without_openvz} \
%{?_without_libpcap} \
%{?_without_macvtap} \
%{?_without_audit} \
+ %{?_without_dtrace} \
--with-qemu-user=%{qemu_user} \
--with-qemu-group=%{qemu_group} \
--with-init-script=redhat \
rm -fr %{buildroot}
%makeinstall
-for i in domain-events/events-c dominfo domsuspend hellolibvirt openauth python xml/nwfilter
+for i in domain-events/events-c dominfo domsuspend hellolibvirt openauth python xml/nwfilter systemtap
do
(cd examples/$i ; make clean ; rm -rf .deps .libs Makefile Makefile.in)
done
%{_sysconfdir}/rc.d/init.d/libvirtd
%config(noreplace) %{_sysconfdir}/sysconfig/libvirtd
%config(noreplace) %{_sysconfdir}/libvirt/libvirtd.conf
+%if %{with_dtrace}
+%{_datadir}/systemtap/tapsets/libvirtd.stp
+%endif
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/qemu/
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/lxc/
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/uml/
%doc examples/domsuspend
%doc examples/openauth
%doc examples/xml
+%doc examples/systemtap
%if %{with_python}
%files python
--without-phyp \
--without-netcf \
--without-audit \
+ --without-dtrace \
--without-libvirtd
make