X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=libust%2Ftracectl.c;h=5439eed5cd0b3c2970fe56292d16b456fe77ec75;hb=ad45e833c116bd1e2e4643932d5aef9d3d6bd924;hp=2d6ced05785f50ebbc61e05d8dc5842fe1dbbafb;hpb=ef290fcae477f5717256af47b4342c0f59948d7a;p=lttng-ust.git diff --git a/libust/tracectl.c b/libust/tracectl.c index 2d6ced05..5439eed5 100644 --- a/libust/tracectl.c +++ b/libust/tracectl.c @@ -138,10 +138,38 @@ void notif_cb(void) } } -static void inform_consumer_daemon(void) +/* Ask the daemon to collect a trace called trace_name and being + * produced by this pid. + * + * The trace must be at least allocated. (It can also be started.) + * This is because _ltt_trace_find is used. + */ + +static void inform_consumer_daemon(const char *trace_name) { - ustcomm_request_consumer(getpid(), "metadata"); - ustcomm_request_consumer(getpid(), "ust"); + int i; + struct ltt_trace_struct *trace; + pid_t pid = getpid(); + int result; + + ltt_lock_traces(); + + trace = _ltt_trace_find(trace_name); + if(trace == NULL) { + WARN("inform_consumer_daemon: could not find trace \"%s\"; it is probably already destroyed", trace_name); + goto finish; + } + + for(i=0; i < trace->nr_channels; i++) { + result = ustcomm_request_consumer(pid, trace->channels[i].channel_name); + if(result == -1) { + WARN("Failed to request collection for channel %s. Is the daemon available?", trace->channels[i].channel_name); + /* continue even if fail */ + } + } + + finish: + ltt_unlock_traces(); } void process_blocked_consumers(void) @@ -253,7 +281,7 @@ void *listener_main(void *p) continue; } - DBG("received a message! it's: %s\n", recvbuf); + DBG("received a message! it's: %s", recvbuf); len = strlen(recvbuf); if(!strcmp(recvbuf, "print_markers")) { @@ -292,7 +320,7 @@ void *listener_main(void *p) return (void *)1; } - inform_consumer_daemon(); + inform_consumer_daemon(trace_name); result = ltt_trace_start(trace_name); if(result < 0) { @@ -807,52 +835,48 @@ static int init_signal_handler(void) return 0; } -static regex_t preg; -static int regex_is_ok = -1; +#define AUTOPROBE_DISABLED 0 +#define AUTOPROBE_ENABLE_ALL 1 +#define AUTOPROBE_ENABLE_REGEX 2 +static int autoprobe_method = AUTOPROBE_DISABLED; +static regex_t autoprobe_regex; static void auto_probe_connect(struct marker *m) { int result; - char* comp_name = NULL; - char* regex; - - if (regex_is_ok != 0) { - goto end; - } + char* concat_name = NULL; + const char *probe_name = "default"; - if (asprintf(&comp_name, "%s/%s", m->channel, m->name) == -1) { - ERR("auto_probe_connect: `asprintf' failed (marker %s/%s)", - m->channel, m->name); + if(autoprobe_method == AUTOPROBE_DISABLED) { return; } - if (regexec(&preg, comp_name, 0, NULL, 0) != 0) { - goto end; /* Not matching */ + else if(autoprobe_method == AUTOPROBE_ENABLE_REGEX) { + result = asprintf(&concat_name, "%s/%s", m->channel, m->name); + if(result == -1) { + ERR("auto_probe_connect: asprintf failed (marker %s/%s)", + m->channel, m->name); + return; + } + if (regexec(&autoprobe_regex, concat_name, 0, NULL, 0)) { + free(concat_name); + return; + } + free(concat_name); } -// connect: - - result = ltt_marker_connect(m->channel, m->name, "default"); + result = ltt_marker_connect(m->channel, m->name, probe_name); if(result && result != -EEXIST) ERR("ltt_marker_connect (marker = %s/%s, errno = %d)", m->channel, m->name, -result); - DBG("just auto connected marker %s %s to probe default", m->channel, m->name); + DBG("auto connected marker %s %s to probe default", m->channel, m->name); - end: - if (comp_name != NULL) { - free(comp_name); - } -} - -static void __attribute__((constructor(101))) init0() -{ - DBG("UST_AUTOPROBE constructor"); } static void __attribute__((constructor(1000))) init() { int result; - char* regex = NULL; + char* autoprobe_val = NULL; /* Initialize RCU in case the constructor order is not good. */ urcu_init(); @@ -860,7 +884,7 @@ static void __attribute__((constructor(1000))) init() /* It is important to do this before events start to be generated. */ ust_register_thread(); - DBG("UST_TRACE constructor"); + DBG("Tracectl constructor"); /* Must create socket before signal handler to prevent races. */ @@ -875,12 +899,11 @@ static void __attribute__((constructor(1000))) init() return; } - regex = getenv("UST_AUTOPROBE"); - if(regex) { - char* regex = NULL; + autoprobe_val = getenv("UST_AUTOPROBE"); + if(autoprobe_val) { struct marker_iter iter; - DBG("IN AUTOPROBE\n"); + DBG("Autoprobe enabled."); /* Ensure markers are initialized */ //init_markers(); @@ -891,18 +914,33 @@ static void __attribute__((constructor(1000))) init() /* first, set the callback that will connect the * probe on new markers */ - marker_set_new_marker_cb(auto_probe_connect); - regex_is_ok = regcomp(&preg, regex, 0); - if (regex_is_ok) { - ERR("cannot parse regex %s", regex); + if(autoprobe_val[0] == '/') { + result = regcomp(&autoprobe_regex, autoprobe_val+1, 0); + if (result) { + char regexerr[150]; + + regerror(result, &autoprobe_regex, regexerr, sizeof(regexerr)); + ERR("cannot parse regex %s (%s), will ignore UST_AUTOPROBE", autoprobe_val, regexerr); + /* don't crash the application just for this */ + } + else { + autoprobe_method = AUTOPROBE_ENABLE_REGEX; + } + } + else { + /* just enable all instrumentation */ + autoprobe_method = AUTOPROBE_ENABLE_ALL; } + + marker_set_new_marker_cb(auto_probe_connect); + /* Now, connect the probes that were already registered. */ marker_iter_reset(&iter); marker_iter_start(&iter); - DBG("now iterating on markers already registered\n"); + DBG("now iterating on markers already registered"); while(iter.marker) { - DBG("now iterating on marker %s\n", iter.marker->name); + DBG("now iterating on marker %s", iter.marker->name); auto_probe_connect(iter.marker); marker_iter_next(&iter); } @@ -944,12 +982,13 @@ static void __attribute__((constructor(1000))) init() return; } + inform_consumer_daemon(trace_name); + result = ltt_trace_start(trace_name); if(result < 0) { ERR("ltt_trace_start failed"); return; } - inform_consumer_daemon(); } @@ -1091,7 +1130,6 @@ void ust_fork(void) init_socket(); have_listener = 0; create_listener(); - ustcomm_request_consumer(getpid(), "metadata"); - ustcomm_request_consumer(getpid(), "ust"); + inform_consumer_daemon("auto"); }