qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

qmp.c (5047B)


      1 /*
      2  * QMP commands for tracing events.
      3  *
      4  * Copyright (C) 2014-2016 LluĂ­s Vilanova <vilanova@ac.upc.edu>
      5  *
      6  * This work is licensed under the terms of the GNU GPL, version 2 or later.
      7  * See the COPYING file in the top-level directory.
      8  */
      9 
     10 #include "qemu/osdep.h"
     11 #include "qapi/error.h"
     12 #include "qapi/qapi-commands-trace.h"
     13 #include "control-vcpu.h"
     14 
     15 
     16 static CPUState *get_cpu(bool has_vcpu, int vcpu, Error **errp)
     17 {
     18     if (has_vcpu) {
     19         CPUState *cpu = qemu_get_cpu(vcpu);
     20         if (cpu == NULL) {
     21             error_setg(errp, "invalid vCPU index %u", vcpu);
     22         }
     23         return cpu;
     24     } else {
     25         return NULL;
     26     }
     27 }
     28 
     29 static bool check_events(bool has_vcpu, bool ignore_unavailable, bool is_pattern,
     30                          const char *name, Error **errp)
     31 {
     32     if (!is_pattern) {
     33         TraceEvent *ev = trace_event_name(name);
     34 
     35         /* error for non-existing event */
     36         if (ev == NULL) {
     37             error_setg(errp, "unknown event \"%s\"", name);
     38             return false;
     39         }
     40 
     41         /* error for non-vcpu event */
     42         if (has_vcpu && !trace_event_is_vcpu(ev)) {
     43             error_setg(errp, "event \"%s\" is not vCPU-specific", name);
     44             return false;
     45         }
     46 
     47         /* error for unavailable event */
     48         if (!ignore_unavailable && !trace_event_get_state_static(ev)) {
     49             error_setg(errp, "event \"%s\" is disabled", name);
     50             return false;
     51         }
     52 
     53         return true;
     54     } else {
     55         /* error for unavailable events */
     56         TraceEventIter iter;
     57         TraceEvent *ev;
     58         trace_event_iter_init_pattern(&iter, name);
     59         while ((ev = trace_event_iter_next(&iter)) != NULL) {
     60             if (!ignore_unavailable && !trace_event_get_state_static(ev)) {
     61                 error_setg(errp, "event \"%s\" is disabled", trace_event_get_name(ev));
     62                 return false;
     63             }
     64         }
     65         return true;
     66     }
     67 }
     68 
     69 TraceEventInfoList *qmp_trace_event_get_state(const char *name,
     70                                               bool has_vcpu, int64_t vcpu,
     71                                               Error **errp)
     72 {
     73     Error *err = NULL;
     74     TraceEventInfoList *events = NULL;
     75     TraceEventIter iter;
     76     TraceEvent *ev;
     77     bool is_pattern = trace_event_is_pattern(name);
     78     CPUState *cpu;
     79 
     80     /* Check provided vcpu */
     81     cpu = get_cpu(has_vcpu, vcpu, &err);
     82     if (err) {
     83         error_propagate(errp, err);
     84         return NULL;
     85     }
     86 
     87     /* Check events */
     88     if (!check_events(has_vcpu, true, is_pattern, name, errp)) {
     89         return NULL;
     90     }
     91 
     92     /* Get states (all errors checked above) */
     93     trace_event_iter_init_pattern(&iter, name);
     94     while ((ev = trace_event_iter_next(&iter)) != NULL) {
     95         TraceEventInfo *value;
     96         bool is_vcpu = trace_event_is_vcpu(ev);
     97         if (has_vcpu && !is_vcpu) {
     98             continue;
     99         }
    100 
    101         value = g_new(TraceEventInfo, 1);
    102         value->vcpu = is_vcpu;
    103         value->name = g_strdup(trace_event_get_name(ev));
    104 
    105         if (!trace_event_get_state_static(ev)) {
    106             value->state = TRACE_EVENT_STATE_UNAVAILABLE;
    107         } else {
    108             if (has_vcpu) {
    109                 if (is_vcpu) {
    110                     if (trace_event_get_vcpu_state_dynamic(cpu, ev)) {
    111                         value->state = TRACE_EVENT_STATE_ENABLED;
    112                     } else {
    113                         value->state = TRACE_EVENT_STATE_DISABLED;
    114                     }
    115                 }
    116                 /* else: already skipped above */
    117             } else {
    118                 if (trace_event_get_state_dynamic(ev)) {
    119                     value->state = TRACE_EVENT_STATE_ENABLED;
    120                 } else {
    121                     value->state = TRACE_EVENT_STATE_DISABLED;
    122                 }
    123             }
    124         }
    125         QAPI_LIST_PREPEND(events, value);
    126     }
    127 
    128     return events;
    129 }
    130 
    131 void qmp_trace_event_set_state(const char *name, bool enable,
    132                                bool has_ignore_unavailable, bool ignore_unavailable,
    133                                bool has_vcpu, int64_t vcpu,
    134                                Error **errp)
    135 {
    136     Error *err = NULL;
    137     TraceEventIter iter;
    138     TraceEvent *ev;
    139     bool is_pattern = trace_event_is_pattern(name);
    140     CPUState *cpu;
    141 
    142     /* Check provided vcpu */
    143     cpu = get_cpu(has_vcpu, vcpu, &err);
    144     if (err) {
    145         error_propagate(errp, err);
    146         return;
    147     }
    148 
    149     /* Check events */
    150     if (!check_events(has_vcpu, has_ignore_unavailable && ignore_unavailable,
    151                       is_pattern, name, errp)) {
    152         return;
    153     }
    154 
    155     /* Apply changes (all errors checked above) */
    156     trace_event_iter_init_pattern(&iter, name);
    157     while ((ev = trace_event_iter_next(&iter)) != NULL) {
    158         if (!trace_event_get_state_static(ev) ||
    159             (has_vcpu && !trace_event_is_vcpu(ev))) {
    160             continue;
    161         }
    162         if (has_vcpu) {
    163             trace_event_set_vcpu_state_dynamic(cpu, ev, enable);
    164         } else {
    165             trace_event_set_state_dynamic(ev, enable);
    166         }
    167     }
    168 }