static void do_trace_enable_events(const char *line_buf) { const bool enable = ('-' != line_buf[0]); const char *line_ptr = enable ? line_buf : line_buf + 1; if (trace_event_is_pattern(line_ptr)) { TraceEvent *ev = NULL; while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) { if (trace_event_get_state_static(ev)) { trace_event_set_state_dynamic(ev, enable); } } } else { TraceEvent *ev = trace_event_name(line_ptr); if (ev == NULL) { error_report("WARNING: trace event '%s' does not exist", line_ptr); } else if (!trace_event_get_state_static(ev)) { error_report("WARNING: trace event '%s' is not traceable", line_ptr); } else { trace_event_set_state_dynamic(ev, enable); } } }
void qmp_trace_event_set_state(const char *name, bool enable, bool has_ignore_unavailable, bool ignore_unavailable, Error **errp) { bool found = false; TraceEvent *ev; /* Check all selected events are dynamic */ ev = NULL; while ((ev = trace_event_pattern(name, ev)) != NULL) { found = true; if (!(has_ignore_unavailable && ignore_unavailable) && !trace_event_get_state_static(ev)) { error_setg(errp, "cannot set dynamic tracing state for \"%s\"", trace_event_get_name(ev)); return; } } if (!found && !trace_event_is_pattern(name)) { error_setg(errp, "unknown event \"%s\"", name); return; } /* Apply changes */ ev = NULL; while ((ev = trace_event_pattern(name, ev)) != NULL) { if (trace_event_get_state_static(ev)) { trace_event_set_state_dynamic(ev, enable); } } }
static void trace_init_events(const char *fname) { Location loc; FILE *fp; char line_buf[1024]; size_t line_idx = 0; if (fname == NULL) { return; } loc_push_none(&loc); loc_set_file(fname, 0); fp = fopen(fname, "r"); if (!fp) { error_report("%s", strerror(errno)); exit(1); } while (fgets(line_buf, sizeof(line_buf), fp)) { loc_set_file(fname, ++line_idx); size_t len = strlen(line_buf); if (len > 1) { /* skip empty lines */ line_buf[len - 1] = '\0'; if ('#' == line_buf[0]) { /* skip commented lines */ continue; } const bool enable = ('-' != line_buf[0]); char *line_ptr = enable ? line_buf : line_buf + 1; if (trace_event_is_pattern(line_ptr)) { TraceEvent *ev = NULL; while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) { if (trace_event_get_state_static(ev)) { trace_event_set_state_dynamic(ev, enable); } } } else { TraceEvent *ev = trace_event_name(line_ptr); if (ev == NULL) { error_report("WARNING: trace event '%s' does not exist", line_ptr); } else if (!trace_event_get_state_static(ev)) { error_report("WARNING: trace event '%s' is not traceable\n", line_ptr); } else { trace_event_set_state_dynamic(ev, enable); } } } } if (fclose(fp) != 0) { loc_set_file(fname, 0); error_report("%s", strerror(errno)); exit(1); } loc_pop(&loc); }
TraceEventInfoList *qmp_trace_event_get_state(const char *name, Error **errp) { TraceEventInfoList *events = NULL; bool found = false; TraceEvent *ev; ev = NULL; while ((ev = trace_event_pattern(name, ev)) != NULL) { TraceEventInfoList *elem = g_new(TraceEventInfoList, 1); elem->value = g_new(TraceEventInfo, 1); elem->value->name = g_strdup(trace_event_get_name(ev)); if (!trace_event_get_state_static(ev)) { elem->value->state = TRACE_EVENT_STATE_UNAVAILABLE; } else if (!trace_event_get_state_dynamic(ev)) { elem->value->state = TRACE_EVENT_STATE_DISABLED; } else { elem->value->state = TRACE_EVENT_STATE_ENABLED; } elem->next = events; events = elem; found = true; } if (!found && !trace_event_is_pattern(name)) { error_setg(errp, "unknown event \"%s\"", name); } return events; }
void trace_print_events(FILE *stream, fprintf_function stream_printf) { TraceEventID i; for (i = 0; i < trace_event_count(); i++) { TraceEvent *ev = trace_event_id(i); stream_printf(stream, "%s [Event ID %u] : state %u\n", trace_event_get_name(ev), i, trace_event_get_state_static(ev) && trace_event_get_state_dynamic(ev)); } }
static bool check_events(bool has_vcpu, bool ignore_unavailable, bool is_pattern, const char *name, Error **errp) { if (!is_pattern) { TraceEvent *ev = trace_event_name(name); /* error for non-existing event */ if (ev == NULL) { error_setg(errp, "unknown event \"%s\"", name); return false; } /* error for non-vcpu event */ if (has_vcpu && !trace_event_is_vcpu(ev)) { error_setg(errp, "event \"%s\" is not vCPU-specific", name); return false; } /* error for unavailable event */ if (!ignore_unavailable && !trace_event_get_state_static(ev)) { error_setg(errp, "event \"%s\" is disabled", name); return false; } return true; } else { /* error for unavailable events */ TraceEventIter iter; TraceEvent *ev; trace_event_iter_init(&iter, name); while ((ev = trace_event_iter_next(&iter)) != NULL) { if (!ignore_unavailable && !trace_event_get_state_static(ev)) { error_setg(errp, "event \"%s\" is disabled", trace_event_get_name(ev)); return false; } } return true; } }
void trace_event_set_state_dynamic(TraceEvent *ev, bool state) { TraceEventID id; bool state_pre; assert(trace_event_get_state_static(ev)); id = trace_event_get_id(ev); /* * We ignore the "vcpu" property here, since there's no target code. Then * dstate can only be 1 or 0. */ state_pre = trace_events_dstate[id]; if (state_pre != state) { if (state) { trace_events_enabled_count++; trace_events_dstate[id] = 1; } else { trace_events_enabled_count--; trace_events_dstate[id] = 0; } } }
void qmp_trace_event_set_state(const char *name, bool enable, bool has_ignore_unavailable, bool ignore_unavailable, bool has_vcpu, int64_t vcpu, Error **errp) { Error *err = NULL; TraceEventIter iter; TraceEvent *ev; bool is_pattern = trace_event_is_pattern(name); CPUState *cpu; /* Check provided vcpu */ cpu = get_cpu(has_vcpu, vcpu, &err); if (err) { error_propagate(errp, err); return; } /* Check events */ if (!check_events(has_vcpu, has_ignore_unavailable && ignore_unavailable, is_pattern, name, errp)) { return; } /* Apply changes (all errors checked above) */ trace_event_iter_init(&iter, name); while ((ev = trace_event_iter_next(&iter)) != NULL) { if (!trace_event_get_state_static(ev) || (has_vcpu && !trace_event_is_vcpu(ev))) { continue; } if (has_vcpu) { trace_event_set_vcpu_state_dynamic(cpu, ev, enable); } else { trace_event_set_state_dynamic(ev, enable); } } }
TraceEventInfoList *qmp_trace_event_get_state(const char *name, bool has_vcpu, int64_t vcpu, Error **errp) { Error *err = NULL; TraceEventInfoList *events = NULL; TraceEvent *ev; bool is_pattern = trace_event_is_pattern(name); CPUState *cpu; /* Check provided vcpu */ cpu = get_cpu(has_vcpu, vcpu, &err); if (err) { error_propagate(errp, err); return NULL; } /* Check events */ if (!check_events(has_vcpu, true, is_pattern, name, errp)) { return NULL; } /* Get states (all errors checked above) */ ev = NULL; while ((ev = trace_event_pattern(name, ev)) != NULL) { TraceEventInfoList *elem; bool is_vcpu = trace_event_is_vcpu(ev); if (has_vcpu && !is_vcpu) { continue; } elem = g_new(TraceEventInfoList, 1); elem->value = g_new(TraceEventInfo, 1); elem->value->vcpu = is_vcpu; elem->value->name = g_strdup(trace_event_get_name(ev)); if (!trace_event_get_state_static(ev)) { elem->value->state = TRACE_EVENT_STATE_UNAVAILABLE; } else { if (has_vcpu) { if (is_vcpu) { if (trace_event_get_vcpu_state_dynamic(cpu, ev)) { elem->value->state = TRACE_EVENT_STATE_ENABLED; } else { elem->value->state = TRACE_EVENT_STATE_DISABLED; } } /* else: already skipped above */ } else { if (trace_event_get_state_dynamic(ev)) { elem->value->state = TRACE_EVENT_STATE_ENABLED; } else { elem->value->state = TRACE_EVENT_STATE_DISABLED; } } } elem->next = events; events = elem; } return events; }