/* * __ikm_read_enable - reads monitor's enable status * * __does not log errors. * * Returns the current status, or -1 if the monitor does not exist, * __hence not logging errors.
*/ staticint __ikm_read_enable(char *monitor_name)
{ char path[MAX_PATH]; longlong enabled; int retval;
/* * __ikm_find_monitor - find the full name of a possibly nested module * * __does not log errors. * * Returns 1 if we found the monitor, -1 on error and 0 if it does not exist. * The string out_name is populated with the full name, which can be * equal to monitor_name or container/monitor_name if nested
*/ staticint __ikm_find_monitor_name(char *monitor_name, char *out_name)
{ char *available_monitors, container[MAX_DA_NAME_LEN+1], *cursor, *end; int retval = 1;
available_monitors = tracefs_instance_file_read(NULL, "rv/available_monitors", NULL); if (!available_monitors) return -1;
/* * ikm_read_enable - reads monitor's enable status * * Returns the current status, or -1 on error.
*/ staticint ikm_read_enable(char *monitor_name)
{ int enabled;
/* * ikm_write_enable - write to the monitor's enable file * * Return the number of bytes written, -1 on error.
*/ staticint ikm_write_enable(char *monitor_name, char *enable_disable)
{ char path[MAX_PATH]; int retval;
/* * ikm_fill_monitor_definition - fill monitor's definition * * Returns -1 on error, 1 if the monitor does not belong in the container, 0 otherwise. * container can be NULL
*/ staticint ikm_fill_monitor_definition(char *name, struct monitor *ikm, char *container)
{ int enabled; char *desc, *nested_name;
nested_name = strstr(name, ":"); if (nested_name) { /* it belongs in container if it starts with "container:" */ if (container && strstr(name, container) != name) return 1;
*nested_name = '/';
++nested_name;
ikm->nested = 1;
} else { if (container) return 1;
nested_name = name;
ikm->nested = 0;
}
/* * ikm_write_reactor - switch the reactor to *reactor * * Return the number or characters written, -1 on error.
*/ staticint ikm_write_reactor(char *monitor_name, char *reactor)
{ char path[MAX_PATH]; int retval;
/* * ikm_get_current_reactor - get the current enabled reactor * * Reads the reactors file and find the currently enabled * [reactor]. * * Returns a dynamically allocated memory with the current * reactor. NULL otherwise.
*/ staticchar *ikm_get_current_reactor(char *monitor_name)
{ char *reactors = ikm_read_reactor(monitor_name); char *curr_reactor = NULL; char *start; char *end;
if (!reactors) return NULL;
start = strstr(reactors, "["); if (!start) goto out_free;
start++;
end = strstr(start, "]"); if (!end) goto out_free;
*end = '\0';
curr_reactor = calloc(strlen(start) + 1, sizeof(char)); if (!curr_reactor) goto out_free;
strncpy(curr_reactor, start, strlen(start));
debug_msg("ikm: read current reactor %s\n", curr_reactor);
out_free:
free(reactors);
return curr_reactor;
}
staticint ikm_has_id(char *monitor_name)
{ char path[MAX_PATH]; char *format; int has_id;
snprintf(path, MAX_PATH, "events/rv/event_%s/format", monitor_name);
format = tracefs_instance_file_read(NULL, path, NULL); if (!format) {
err_msg("ikm: fail reading monitor's %s format event file\n", monitor_name); return -1;
}
if (config_has_id) { if (missing_id) /* placeholder if we are dealing with a mixed-type container*/
trace_seq_printf(s, " "); else
trace_seq_printf(s, "%8llu ", id);
}
/* * ikm_error_handler - callback to handle error events * * Called any time a rv:"monitor"_errors events is generated. * It parses and prints event.
*/ staticint
ikm_error_handler(struct trace_seq *s, struct tep_record *record, struct tep_event *trace_event, void *context)
{ unsignedlonglong pid, id; int cpu = record->cpu; char *state, *event; int val; bool missing_id;
if (config_has_id)
missing_id = tep_get_field_val(s, trace_event, "id", record, &id, 1);
if (config_has_id) { if (missing_id) /* placeholder if we are dealing with a mixed-type container*/
trace_seq_printf(s, " "); else
trace_seq_printf(s, "%8llu ", id);
}
/* * ikm_setup_trace_instance - set up a tracing instance to collect data * * Create a trace instance, enable rv: events and enable the trace. * * Returns the trace_instance * with all set, NULL otherwise.
*/ staticstruct trace_instance *ikm_setup_trace_instance(char *monitor_name)
{ struct trace_instance *inst; int retval;
if (!config_trace) return NULL;
/* alloc data */
inst = calloc(1, sizeof(*inst)); if (!inst) {
err_msg("ikm: failed to allocate trace instance"); goto out_err;
}
retval = trace_instance_init(inst, monitor_name); if (retval) goto out_free;
if (config_is_container)
retval = ikm_enable_trace_container(monitor_name, inst); else
retval = ikm_enable_trace_events(monitor_name, inst); if (retval) goto out_inst;
/* ready to enable */
tracefs_trace_on(inst->inst);
if (config_reactor) {
config_initial_reactor = ikm_get_current_reactor(monitor_name); if (!config_initial_reactor)
ikm_usage(1, monitor_name, "ikm: failed to read current reactor, are reactors enabled?");
retval = ikm_write_reactor(monitor_name, config_reactor); if (retval <= 0)
ikm_usage(1, monitor_name, "ikm: failed to set %s reactor, is it available?",
config_reactor);
}
debug_msg("ikm: my pid is %d\n", config_my_pid);
return 0;
}
/** * ikm_run_monitor - apply configs and run the monitor * * Returns 1 if a monitor was found an executed, 0 if no * monitors were found, or -1 on error.
*/ int ikm_run_monitor(char *monitor_name, int argc, char **argv)
{ struct trace_instance *inst = NULL; char *nested_name, full_name[2*MAX_DA_NAME_LEN]; int retval;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.