From: Mathieu Desnoyers Date: Sat, 19 Nov 2011 00:06:02 +0000 (-0500) Subject: Implement UST stop command X-Git-Tag: v2.0-pre15~102 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=8be98f9a4419d360bce0678981ba3f4b891b0a19;ds=sidebyside Implement UST stop command Signed-off-by: Mathieu Desnoyers --- diff --git a/lttng-sessiond/main.c b/lttng-sessiond/main.c index 2e6292d38..9464c2c1b 100644 --- a/lttng-sessiond/main.c +++ b/lttng-sessiond/main.c @@ -2596,11 +2596,11 @@ static int cmd_stop_trace(struct ltt_session *session) int ret; struct ltt_kernel_channel *kchan; struct ltt_kernel_session *ksession; - //struct ltt_ust_session *usess; - //struct ltt_ust_channel *ustchan; + struct ltt_ust_session *usess; /* Short cut */ ksession = session->kernel_session; + usess = session->ust_session; if (!session->enabled) return LTTCOMM_UST_START_FAIL; @@ -2632,32 +2632,16 @@ static int cmd_stop_trace(struct ltt_session *session) kernel_wait_quiescent(kernel_tracer_fd); } -#ifdef DISABLE - /* Stop each UST session */ - DBG("Stop UST tracing"); - cds_list_for_each_entry(usess, &session->ust_session_list.head, list) { - /* Flush all buffers before stopping */ - ret = ustctl_flush_buffer(usess->sock, usess->metadata->obj); - if (ret < 0) { - ERR("UST metadata flush failed"); - } - - cds_list_for_each_entry(ustchan, &usess->channels.head, list) { - ret = ustctl_flush_buffer(usess->sock, ustchan->obj); - if (ret < 0) { - ERR("UST flush buffer error"); - } - } + /* Flag session that trace should start automatically */ + if (usess) { + usess->start_trace = 0; - ret = ustctl_stop_session(usess->sock, usess->handle); + ret = ust_app_stop_trace_all(usess); if (ret < 0) { - ret = LTTCOMM_KERN_STOP_FAIL; + ret = LTTCOMM_UST_START_FAIL; goto error; } - - ustctl_wait_quiescent(usess->sock); } -#endif ret = LTTCOMM_OK; diff --git a/lttng-sessiond/ust-app.c b/lttng-sessiond/ust-app.c index 46c3dfdc1..3547679f8 100644 --- a/lttng-sessiond/ust-app.c +++ b/lttng-sessiond/ust-app.c @@ -1122,6 +1122,10 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app) goto error_rcu_unlock; } + /* upon restart, we skip the setup, already done */ + if (ua_sess->started) + goto skip_setup; + ret = create_ust_app_metadata(ua_sess, usess->pathname, app); if (ret < 0) { goto error_rcu_unlock; @@ -1165,7 +1169,9 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app) if (ret < 0) { goto error_rcu_unlock; } + ua_sess->started = 1; +skip_setup: /* This start the UST tracing */ ret = ustctl_start_session(app->key.sock, ua_sess->handle); if (ret < 0) { @@ -1185,6 +1191,59 @@ error_rcu_unlock: return -1; } +/* + * Stop tracing for a specific UST session and app. + */ +int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app) +{ + int ret = 0; + struct ust_app_session *ua_sess; + + DBG("Stopping tracing for ust app pid %d", app->key.pid); + + rcu_read_lock(); + + ua_sess = lookup_session_by_app(usess, app); + if (ua_sess == NULL) { + /* Only malloc can failed so something is really wrong */ + goto error_rcu_unlock; + } + +#if 0 /* only useful when periodical flush will be supported */ + /* need to keep a handle on shm in session for this. */ + /* Flush all buffers before stopping */ + ret = ustctl_flush_buffer(usess->sock, usess->metadata->obj); + if (ret < 0) { + ERR("UST metadata flush failed"); + } + + cds_list_for_each_entry(ustchan, &usess->channels.head, list) { + ret = ustctl_flush_buffer(usess->sock, ustchan->obj); + if (ret < 0) { + ERR("UST flush buffer error"); + } + } +#endif + + /* This inhibits UST tracing */ + ret = ustctl_stop_session(app->key.sock, ua_sess->handle); + if (ret < 0) { + ERR("Error stopping tracing for app pid: %d", app->key.pid); + goto error_rcu_unlock; + } + + rcu_read_unlock(); + + /* Quiescent wait after stopping trace */ + ustctl_wait_quiescent(app->key.sock); + + return 0; + +error_rcu_unlock: + rcu_read_unlock(); + return -1; +} + /* * Start tracing for the UST session. */ @@ -1211,6 +1270,32 @@ int ust_app_start_trace_all(struct ltt_ust_session *usess) return 0; } +/* + * Start tracing for the UST session. + */ +int ust_app_stop_trace_all(struct ltt_ust_session *usess) +{ + int ret = 0; + struct cds_lfht_iter iter; + struct ust_app *app; + + DBG("Stopping all UST traces"); + + rcu_read_lock(); + + cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) { + ret = ust_app_stop_trace(usess, app); + if (ret < 0) { + /* Continue to next apps even on error */ + continue; + } + } + + rcu_read_unlock(); + + return 0; +} + /* * Add channels/events from UST global domain to registered apps at sock. */ diff --git a/lttng-sessiond/ust-app.h b/lttng-sessiond/ust-app.h index f8b0c6c6d..3159ba5cb 100644 --- a/lttng-sessiond/ust-app.h +++ b/lttng-sessiond/ust-app.h @@ -78,6 +78,8 @@ struct ust_app_channel { struct ust_app_session { int enabled; + /* started: has the session been in started state at any time ? */ + int started; /* allows detection of start vs restart. */ int handle; /* Used has unique identifier */ unsigned int uid; struct ltt_ust_metadata *metadata; @@ -113,7 +115,9 @@ int ust_app_create_event_all(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent); unsigned long ust_app_list_count(void); int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app); +int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app); int ust_app_start_trace_all(struct ltt_ust_session *usess); +int ust_app_stop_trace_all(struct ltt_ust_session *usess); int ust_app_list_events(struct lttng_event **events); void ust_app_global_update(struct ltt_ust_session *usess, int sock);