From: Xinghai Yu <yuxinghai@xxxxxxxxxxxxxx> Using the macro exported by configure.ac to decide which trace backend to build for libvirt. We got 3 trace macros now: WITH_TRACE_PROBES, if --with-ftrace or --with-dtrace option was set, this macro would be true and it tell the codes that we will use trace function, dtrace or ftrace will be supported in libvirt. WITH_DTRACE_PROBES, if --with-dtrace was set this macro would be true and the ftrace will be supported in libvirt. The ftrace backend code turn on the tracing function of deugfs and store fd of the ftrace buffer '/sys/kernel/debug/tracing/trace_marker'. Then let the 'trace_backend_init()' function be called in the initial process of other programs so that the trace info of them can be transfered to the ftrace's buffer. The user can get trace info in interface '/sys/kernel/debug/tracing/trace'. Signed-off-by: Xinghai Yu <yuxinghai@xxxxxxxxxxxxxx> Cc: Eiichi Tsukata <eiichi.tsukata.xh@xxxxxxxxxxx> --- configure.ac | 24 ++++++++++++-- daemon/Makefile.am | 3 ++ src/Makefile.am | 66 ++++++++++++++++++++++++++++++--------- src/ftrace.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ftrace.h | 14 +++++++++ tests/Makefile.am | 3 ++ tools/virsh.c | 3 ++ 7 files changed, 188 insertions(+), 16 deletions(-) create mode 100644 src/ftrace.c create mode 100644 src/ftrace.h diff --git a/configure.ac b/configure.ac index 63744ee..6f0992f 100644 --- a/configure.ac +++ b/configure.ac @@ -1476,6 +1476,25 @@ if test "$with_apparmor" = "no"; then fi AM_CONDITIONAL([WITH_APPARMOR_PROFILES], [test "$with_apparmor_profiles" != "no"]) +dnl FTrace trace +AC_ARG_WITH([ftrace], + [AS_HELP_STRING([--with-ftrace], + [use ftrace for tracing @<:@default=check@:>@])], + [], + [with_ftrace=check]) + +if test "$with_ftrace" != "no" ; then + if test "$with_linux" = "yes"; then + with_ftrace=yes + else + with_ftrace=no + fi + if test "$with_ftrace" = "yes"; then + AC_DEFINE_UNQUOTED([WITH_FTRACE_PROBES], 1, [whether FTrace are available]) + fi +fi +AM_CONDITIONAL([WITH_FTRACE_PROBES], [test "$with_ftrace" != "no"]) + dnl DTrace static probes AC_ARG_WITH([dtrace], [AS_HELP_STRING([--with-dtrace], @@ -1500,10 +1519,10 @@ if test "$with_dtrace" != "no" ; then fi AM_CONDITIONAL([WITH_DTRACE_PROBES], [test "$with_dtrace" != "no"]) -if test "$with_dtrace" = "yes"; then +if test "$with_dtrace" = "yes" || test "$with_ftrace" = "yes"; then AC_DEFINE_UNQUOTED([WITH_TRACE_PROBES], 1, [whether Trace function are available]) fi -AM_CONDITIONAL([WITH_TRACE_PROBES], [test "$with_dtrace" != "no"]) +AM_CONDITIONAL([WITH_TRACE_PROBES], [test "$with_dtrace" != "no" || test "$with_ftrace" != "no"]) dnl numad AC_ARG_WITH([numad], @@ -2856,6 +2875,7 @@ AC_MSG_NOTICE([ Debug: $enable_debug]) AC_MSG_NOTICE([ Use -Werror: $set_werror]) AC_MSG_NOTICE([ Warning Flags: $WARN_CFLAGS]) AC_MSG_NOTICE([ DTrace: $with_dtrace]) +AC_MSG_NOTICE([ FTrace: $with_ftrace]) AC_MSG_NOTICE([ numad: $with_numad]) AC_MSG_NOTICE([ XML Catalog: $XML_CATALOG_FILE]) AC_MSG_NOTICE([ Init script: $with_init_script]) diff --git a/daemon/Makefile.am b/daemon/Makefile.am index bd77623..8637978 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -166,6 +166,9 @@ endif WITH_TRACE_PROBES if WITH_DTRACE_PROBES libvirtd_LDADD += ../src/libvirt_probes_dtrace.lo endif WITH_DTRACE_PROBES +if WITH_FTRACE_PROBES +libvirtd_LDADD += ../src/libvirt_ftrace.la +endif WITH_FTRACE_PROBES libvirtd_LDADD += \ libvirtd_conf.la \ diff --git a/src/Makefile.am b/src/Makefile.am index 0e50ebc..6325864 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1979,6 +1979,18 @@ CLEANFILES += libvirt_probes.c libvirt_probes.h libvirt_probes.o libvirt_probes. libvirt_qemu_probes.lo endif +if WITH_FTRACE_PROBES +noinst_LTLIBRARIES += libvirt_ftrace.la +libvirt_la_BUILT_LIBADD += libvirt_ftrace.la +libvirt_ftrace_la_SOURCES = ftrace.c ftrace.h +libvirt_ftrace_la_LDFLAGS = $(AM_LDFLAGS) +libvirt_ftrace_la_CFLAGS = $(AM_CFLAGS) +BUILT_SOURCES += ftrace.c ftrace.h +if WITH_QEMU +libvirt_driver_qemu_impl_la_LIBADD += libvirt_ftrace.la +endif WITH_QEMU +endif WITH_FTRACE_PROBES + if WITH_DTRACE_PROBES libvirt_la_BUILT_LIBADD += libvirt_probes_dtrace.lo libvirt_la_DEPENDENCIES += libvirt_probes_dtrace.o libvirt_probes_dtrace.lo @@ -2171,6 +2183,9 @@ endif WITH_TRACE_PROBES if WITH_DTRACE_PROBES lockd_la_LIBADD += libvirt_probes_dtrace.lo endif WITH_DTRACE_PROBES +if WITH_FTRACE_PROBES +lockd_la_LIBADD += libvirt_ftrace.la +endif WITH_FTRACE_PROBES if WITH_QEMU nodist_conf_DATA += locking/qemu-lockd.conf BUILT_SOURCES += locking/qemu-lockd.conf @@ -2203,16 +2218,21 @@ virtlockd_LDFLAGS = \ virtlockd_LDADD = \ libvirt-net-rpc-server.la \ libvirt-net-rpc.la \ - libvirt_util.la \ - ../gnulib/lib/libgnu.la \ - $(CYGWIN_EXTRA_LIBADD) \ - $(NULL) + libvirt_util.la if WITH_TRACE_PROBES virtlockd_LDADD += libvirt_probes.lo endif WITH_TRACE_PROBES if WITH_DTRACE_PROBES virtlockd_LDADD += libvirt_probes_dtrace.lo endif WITH_DTRACE_PROBES +if WITH_FTRACE_PROBES +virtlockd_LDADD += libvirt_ftrace.la +endif WITH_FTRACE_PROBES +# Library 'libgnu.la' must be added last, since functions it provides/replaces +# are used by 'libvirt_ftrace.la' library. +virtlockd_LDADD += ../gnulib/lib/libgnu.la \ + $(CYGWIN_EXTRA_LIBADD) \ + $(NULL) else ! WITH_LIBVIRTD EXTRA_DIST += $(LOCK_DAEMON_SOURCES) \ @@ -2489,15 +2509,19 @@ libvirt_iohelper_LDFLAGS = \ $(AM_LDFLAGS) \ $(PIE_LDFLAGS) \ $(NULL) -libvirt_iohelper_LDADD = \ - libvirt_util.la \ - ../gnulib/lib/libgnu.la +libvirt_iohelper_LDADD = libvirt_util.la if WITH_TRACE_PROBES libvirt_iohelper_LDADD += libvirt_probes.lo endif WITH_TRACE_PROBES if WITH_DTRACE_PROBES libvirt_iohelper_LDADD += libvirt_probes_dtrace.lo endif WITH_DTRACE_PROBES +if WITH_FTRACE_PROBES +libvirt_iohelper_LDADD += libvirt_ftrace.la +endif WITH_FTRACE_PROBES +# Library 'libgnu.la' must be added last, since functions it provides/replaces +# are used by 'libvirt_ftrace.la' library. +libvirt_iohelper_LDADD += ../gnulib/lib/libgnu.la libvirt_iohelper_CFLAGS = \ $(AM_CFLAGS) \ @@ -2516,14 +2540,19 @@ libvirt_parthelper_LDFLAGS = \ $(NULL) libvirt_parthelper_LDADD = \ $(LIBPARTED_LIBS) \ - libvirt_util.la \ - ../gnulib/lib/libgnu.la + libvirt_util.la if WITH_TRACE_PROBES libvirt_parthelper_LDADD += libvirt_probes.lo endif WITH_TRACE_PROBES if WITH_DTRACE_PROBES libvirt_parthelper_LDADD += libvirt_probes_dtrace.lo endif WITH_DTRACE_PROBES +if WITH_FTRACE_PROBES +libvirt_parthelper_LDADD += libvirt_ftrace.la +endif WITH_FTRACE_PROBES +# Library 'libgnu.la' must be added last, since functions it provides/replaces +# are used by 'libvirt_ftrace.la' library. +libvirt_parthelper_LDADD += ../gnulib/lib/libgnu.la libvirt_parthelper_CFLAGS = \ $(LIBPARTED_CFLAGS) \ @@ -2569,15 +2598,19 @@ libvirt_lxc_LDADD = \ libvirt-net-rpc.la \ libvirt_security_manager.la \ libvirt_conf.la \ - libvirt_util.la \ - ../gnulib/lib/libgnu.la + libvirt_util.la if WITH_TRACE_PROBES libvirt_lxc_LDADD += libvirt_probes.lo endif WITH_TRACE_PROBES if WITH_DTRACE_PROBES libvirt_lxc_LDADD += libvirt_probes_dtrace.lo endif WITH_DTRACE_PROBES -libvirt_lxc_LDADD += $(SECDRIVER_LIBS) +if WITH_FTRACE_PROBES +libvirt_lxc_LDADD += libvirt_ftrace.la +endif WITH_FTRACE_PROBES +# Library 'libgnu.la' must be added last, since functions it provides/replaces +# are used by 'libvirt_ftrace.la' library. +libvirt_lxc_LDADD += ../gnulib/lib/libgnu.la $(SECDRIVER_LIBS) libvirt_lxc_CFLAGS = \ -I$(top_srcdir)/src/conf \ $(AM_CFLAGS) \ @@ -2607,14 +2640,19 @@ virt_aa_helper_LDFLAGS = \ $(NULL) virt_aa_helper_LDADD = \ libvirt_conf.la \ - libvirt_util.la \ - ../gnulib/lib/libgnu.la + libvirt_util.la if WITH_TRACE_PROBES virt_aa_helper_LDADD += libvirt_probes.lo endif WITH_TRACE_PROBES if WITH_DTRACE_PROBES virt_aa_helper_LDADD += libvirt_probes_dtrace.lo endif WITH_DTRACE_PROBES +if WITH_FTRACE_PROBES +virt_aa_helper_LDADD += libvirt_ftrace.la +endif WITH_FTRACE_PROBES +# Library 'libgnu.la' must be added last, since functions it provides/replaces +# are used by 'libvirt_ftrace.la' library. +virt_aa_helper_LDADD += ../gnulib/lib/libgnu.la virt_aa_helper_CFLAGS = \ -I$(top_srcdir)/src/conf \ -I$(top_srcdir)/src/security \ diff --git a/src/ftrace.c b/src/ftrace.c new file mode 100644 index 0000000..a46593f --- /dev/null +++ b/src/ftrace.c @@ -0,0 +1,91 @@ +/* + * Ftrace trace backend + * + * Copyright (C) 2013 Hitachi, Ltd. + * Created by Eiichi Tsukata <eiichi.tsukata.xh@xxxxxxxxxxx> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <fcntl.h> +#include <limits.h> +#include <sys/unistd.h> + +#define _STR(x) #x +#define STR(x) _STR(x) + +int trace_marker_fd; +bool trace_backend_init(void); + +static int find_debugfs(char *debugfs) +{ + char type[100]; + FILE *fp; + + fp = fopen("/proc/mounts", "r"); + if (fp == NULL) { + return 0; + } + + while (fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n", + debugfs, type) == 2) { + if (strcmp(type, "debugfs") == 0) { + break; + } + } + fclose(fp); + + if (strcmp(type, "debugfs") != 0) { + return 0; + } + return 1; +} + +bool trace_backend_init(void) +{ + int debugfs_found; + int trace_fd = -1; + bool ret = true; + char *debugfs = malloc(PATH_MAX); + char *path = malloc(PATH_MAX); + + debugfs_found = find_debugfs(debugfs); + if (debugfs_found) { + snprintf(path, PATH_MAX, "%s/tracing/tracing_on", debugfs); + trace_fd = open(path, O_WRONLY); + if (trace_fd < 0) { + perror("Could not open ftrace 'tracing_on' file"); + ret = false; + goto out; + } else { + if (write(trace_fd, "1", 1) < 0) { + perror("Could not write to 'tracing_on' file"); + close(trace_fd); + ret = false; + goto out; + } + close(trace_fd); + } + snprintf(path, PATH_MAX, "%s/tracing/trace_marker", debugfs); + trace_marker_fd = open(path, O_WRONLY); + if (trace_marker_fd < 0) { + perror("Could not open ftrace 'trace_marker' file"); + ret = false; + goto out; + } + } else { + fprintf(stderr, "debugfs is not mounted\n"); + ret = false; + goto out; + } +out: + free(path); + free(debugfs); + return ret; +} diff --git a/src/ftrace.h b/src/ftrace.h new file mode 100644 index 0000000..0fd88d1 --- /dev/null +++ b/src/ftrace.h @@ -0,0 +1,14 @@ +#ifndef TRACE_FTRACE_H +#define TRACE_FTRACE_H + +#include <stdbool.h> +#include <unistd.h> + +/* the buffer size of qemu_monitor is 1024 */ +#define MAX_TRACE_STRLEN 1024 + +bool trace_backend_init(void); + +extern int trace_marker_fd; + +#endif diff --git a/tests/Makefile.am b/tests/Makefile.am index 8d24cd9..2aa26f5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -51,6 +51,9 @@ endif WITH_TRACE_PROBES if WITH_DTRACE_PROBES PROBES_O += ../src/libvirt_probes_dtrace.lo endif WITH_DTRACE_PROBES +if WITH_FTRACE_PROBES +PROBES_O += ../src/libvirt_ftrace.la +endif WITH_FTRACE_PROBES GNULIB_LIBS = \ ../gnulib/lib/libgnu.la diff --git a/tools/virsh.c b/tools/virsh.c index 2d4aaff..edd41aa 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -3276,6 +3276,9 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED) #ifdef WITH_DTRACE_PROBES vshPrint(ctl, " DTrace"); #endif +#ifdef WITH_FTRACE_PROBES + vshPrint(ctl, " FTrace"); +#endif #if WITH_READLINE vshPrint(ctl, " Readline"); #endif -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list