trace: provide mechanism for registering trace events
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 4 Oct 2016 13:35:52 +0000 (14:35 +0100)
committerStefan Hajnoczi <stefanha@redhat.com>
Wed, 12 Oct 2016 07:52:50 +0000 (09:52 +0200)
Remove the notion of there being a single global array
of trace events, by introducing a method for registering
groups of events.

The module_call_init() needs to be invoked at the start
of any program that wants to make use of the trace
support. Currently this covers system emulators qemu-nbd,
qemu-img and qemu-io.

[Squashed the following fix from Daniel P. Berrange
<berrange@redhat.com>:

linux-user/bsd-user: initialize trace events subsystem

The bsd-user/linux-user programs make use of the CPU emulation
code and this now requires that the trace events subsystem
is enabled, otherwise it'll crash trying to allocate an empty
trace events bitmap for the CPU object.

--Stefan]

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: LluĂ­s Vilanova <vilanova@ac.upc.edu>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 1475588159-30598-14-git-send-email-berrange@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
bsd-user/main.c
include/qemu/module.h
linux-user/main.c
qemu-img.c
qemu-io.c
qemu-nbd.c
scripts/tracetool/format/events_c.py
trace/control-internal.h
trace/control.c
trace/control.h
vl.c

index d8367bda4677b0ca9613e8f1269ed81683ba747a..4fd7b6396dfd04b162e11abcd3c4152477d46e35 100644 (file)
@@ -740,6 +740,7 @@ int main(int argc, char **argv)
     if (argc <= 1)
         usage();
 
+    module_call_init(MODULE_INIT_TRACE);
     qemu_init_cpu_list();
     module_call_init(MODULE_INIT_QOM);
 
index dc2c9d4c4eee7ac6bfadd8853099397045cd0f8f..877cca7d7b643d4d6cfe7f78254cee9b5bbc206d 100644 (file)
@@ -44,6 +44,7 @@ typedef enum {
     MODULE_INIT_OPTS,
     MODULE_INIT_QAPI,
     MODULE_INIT_QOM,
+    MODULE_INIT_TRACE,
     MODULE_INIT_MAX
 } module_init_type;
 
@@ -51,6 +52,7 @@ typedef enum {
 #define opts_init(function) module_init(function, MODULE_INIT_OPTS)
 #define qapi_init(function) module_init(function, MODULE_INIT_QAPI)
 #define type_init(function) module_init(function, MODULE_INIT_QOM)
+#define trace_init(function) module_init(function, MODULE_INIT_TRACE)
 
 #define block_module_load_one(lib) module_load_one("block-", lib)
 
index 9e4b430d66fe9a213f855a5231f4cdd7151fe3f9..0e31dad6846fa1e08fb194155a4a1db18c386288 100644 (file)
@@ -4158,6 +4158,7 @@ int main(int argc, char **argv, char **envp)
     int ret;
     int execfd;
 
+    module_call_init(MODULE_INIT_TRACE);
     qemu_init_cpu_list();
     module_call_init(MODULE_INIT_QOM);
 
index ceffefeacb66e00945de4602042a9106b6a69c1f..02c07b913dd8e00f017715bbe2033f58df640af1 100644 (file)
@@ -4165,6 +4165,7 @@ int main(int argc, char **argv)
     signal(SIGPIPE, SIG_IGN);
 #endif
 
+    module_call_init(MODULE_INIT_TRACE);
     error_set_progname(argv[0]);
     qemu_init_exec_dir(argv[0]);
 
index db129eac5ffca9c21e83ad3917400770cbc33932..23a229f880b15ec44bf26771d04a9d325e03dab5 100644 (file)
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -467,6 +467,7 @@ int main(int argc, char **argv)
     signal(SIGPIPE, SIG_IGN);
 #endif
 
+    module_call_init(MODULE_INIT_TRACE);
     progname = basename(argv[0]);
     qemu_init_exec_dir(argv[0]);
 
index 705b95ec293d10ed3dc643b5743b1332c1645e60..cca4a983b77add95d2fc103960cea010f52bf7c1 100644 (file)
@@ -533,6 +533,7 @@ int main(int argc, char **argv)
     sa_sigterm.sa_handler = termsig_handler;
     sigaction(SIGTERM, &sa_sigterm, NULL);
 
+    module_call_init(MODULE_INIT_TRACE);
     qcrypto_init(&error_fatal);
 
     module_call_init(MODULE_INIT_QOM);
index 40ae39568ec1b87a4f4baa11fb0ef279010185c0..88175559dea36310d3197e7d6301061ecf942874 100644 (file)
@@ -60,3 +60,9 @@ def generate(events, backend):
     out('  NULL,',
         '};',
         '')
+
+    out('static void trace_register_events(void)',
+        '{',
+        '    trace_event_register_group(trace_events);',
+        '}',
+        'trace_init(trace_register_events)')
index 9abbc96bcb48bca4d806332a4a7d0f3034c8e90d..a9d395a58705dbcd094c17e49436e88c1ecebccf 100644 (file)
@@ -15,7 +15,6 @@
 #include "qom/cpu.h"
 
 
-extern TraceEvent *trace_events[];
 extern int trace_events_enabled_count;
 
 
@@ -83,4 +82,7 @@ static inline bool trace_event_get_vcpu_state_dynamic(CPUState *vcpu,
     return trace_event_get_vcpu_state_dynamic_by_vcpu_id(vcpu, vcpu_id);
 }
 
+
+void trace_event_register_group(TraceEvent **events);
+
 #endif /* TRACE__CONTROL_INTERNAL_H */
index 6b32511d60a5e389366cf77cda8bb17df380e64a..a2313273d8808ef413116be4ab270adf8ab7528d 100644 (file)
 
 int trace_events_enabled_count;
 
+typedef struct TraceEventGroup {
+    TraceEvent **events;
+} TraceEventGroup;
+
+static TraceEventGroup *event_groups;
+static size_t nevent_groups;
+
 QemuOptsList qemu_trace_opts = {
     .name = "trace",
     .implied_opt_name = "enable",
@@ -50,6 +57,14 @@ QemuOptsList qemu_trace_opts = {
 };
 
 
+void trace_event_register_group(TraceEvent **events)
+{
+    event_groups = g_renew(TraceEventGroup, event_groups, nevent_groups + 1);
+    event_groups[nevent_groups].events = events;
+    nevent_groups++;
+}
+
+
 TraceEvent *trace_event_name(const char *name)
 {
     assert(name != NULL);
@@ -100,14 +115,20 @@ static bool pattern_glob(const char *pat, const char *ev)
 void trace_event_iter_init(TraceEventIter *iter, const char *pattern)
 {
     iter->event = 0;
+    iter->group = 0;
     iter->pattern = pattern;
 }
 
 TraceEvent *trace_event_iter_next(TraceEventIter *iter)
 {
-    while (trace_events[iter->event] != NULL) {
-        TraceEvent *ev = trace_events[iter->event];
+    while (iter->group < nevent_groups &&
+           event_groups[iter->group].events[iter->event] != NULL) {
+        TraceEvent *ev = event_groups[iter->group].events[iter->event];
         iter->event++;
+        if (event_groups[iter->group].events[iter->event] == NULL) {
+            iter->event = 0;
+            iter->group++;
+        }
         if (!iter->pattern ||
             pattern_glob(iter->pattern,
                          trace_event_get_name(ev))) {
index cccd2a295eba603e3e50f6511c787e13bd250ccd..3f30a0c2b77cde76fd60867b9faa7e831923d6d2 100644 (file)
@@ -15,6 +15,7 @@
 
 typedef struct TraceEventIter {
     size_t event;
+    size_t group;
     const char *pattern;
 } TraceEventIter;
 
diff --git a/vl.c b/vl.c
index eb3c5ee3484d5c9d7b863ced1b0474ab3f5b064e..c657acdd3c7f31c7b09b4b63dbe83d890c76fb38 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -3024,6 +3024,8 @@ int main(int argc, char **argv, char **envp)
     Error *err = NULL;
     bool list_data_dirs = false;
 
+    module_call_init(MODULE_INIT_TRACE);
+
     qemu_init_cpu_list();
     qemu_init_cpu_loop();
     qemu_mutex_lock_iothread();