line_len = getline(lp, &buf_len, tracer->trace_pipe); if (line_len == -1) break;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
op = tracer->process_line(*lp);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
if (tracer->expecting_more) {
pthread_mutex_lock(&tracer->met_all_expected_lock); if (!tracer->expecting_more())
pthread_cond_signal(&tracer->met_all_expected);
pthread_mutex_unlock(&tracer->met_all_expected_lock);
}
if (op == FTRACER_LINE_DISCARD) continue; if (op == FTRACER_EXIT) break; if (op != FTRACER_LINE_PRESERVE)
test_error("unexpected tracer command %d", op);
tracer->next_line_ind++;
buf_len = 0;
}
test_print("too many lines in ftracer buffer %zu, exiting tracer",
tracer->next_line_ind);
pthread_cleanup_pop(1); return NULL;
}
staticint setup_trace_thread(struct test_ftracer *tracer)
{ int ret = 0; char *path;
path = test_sprintf("%s/trace_pipe", tracer->instance_path); if (!path) return -ENOMEM;
tracer->trace_pipe = fopen(path, "r"); if (!tracer->trace_pipe) {
ret = -errno; goto out_free;
}
if (pthread_create(&tracer->tracer_thread, NULL,
tracer_thread_func, (void *)tracer)) {
ret = -errno;
fclose(tracer->trace_pipe);
}
while (tracer->expecting_more() && ret != ETIMEDOUT)
ret = pthread_cond_timedwait(&tracer->met_all_expected,
&tracer->met_all_expected_lock, &timeout);
pthread_mutex_unlock(&tracer->met_all_expected_lock);
}
int setup_trace_event(struct test_ftracer *tracer, constchar *event, constchar *filter)
{ char *enable_path, *filter_path, *instance = tracer->instance_path; int ret;
enable_path = test_sprintf("%s/events/%s/enable", instance, event); if (!enable_path) return -ENOMEM;
filter_path = test_sprintf("%s/events/%s/filter", instance, event); if (!filter_path) {
ret = -ENOMEM; goto out_free;
}
ret = test_echo(filter_path, 0, "%s", filter); if (!ret)
ret = test_echo(enable_path, 0, "1");
final_wait_for_events(tracer, TEST_TIMEOUT_SEC);
stop_trace_thread(tracer);
remove_ftrace_instance(tracer); if (tracer->destructor)
tracer->destructor(tracer); for (i = 0; i < tracer->saved_lines_size; i++)
free(tracer->saved_lines[i]);
pthread_cond_destroy(&tracer->met_all_expected);
pthread_mutex_destroy(&tracer->met_all_expected_lock);
free(tracer);
}
int test_setup_tracing(void)
{ /* * Just a basic protection - this should be called only once from * lib/kconfig. Not thread safe, which is fine as it's early, before * threads are created.
*/ staticint already_set; int err;
if (already_set) return -1;
/* Needs net-namespace cookies for filters */ if (ns_cookie1 == ns_cookie2) {
test_print("net-namespace cookies: %" PRIu64 " == %" PRIu64 ", can't set up tracing",
ns_cookie1, ns_cookie2); return -1;
}
already_set = 1;
test_add_destructor(test_unset_tracing);
err = mount_ftrace(); if (err) {
test_print("failed to mount_ftrace(): %d", err); return err;
}
return setup_aolib_ftracer();
}
staticint get_ns_cookie(int nsfd, uint64_t *out)
{ int old_ns = switch_save_ns(nsfd);
socklen_t size = sizeof(*out); int sk;
sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sk < 0) {
test_print("socket(): %m"); return -errno;
}
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.