Implement UST stop command
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 19 Nov 2011 00:06:02 +0000 (19:06 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 19 Nov 2011 00:06:02 +0000 (19:06 -0500)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lttng-sessiond/main.c
lttng-sessiond/ust-app.c
lttng-sessiond/ust-app.h

index 2e6292d38a7e567b84d96484d8be22c10f9e28eb..9464c2c1b8e0f4f3d17ef300cf15975d2174c6ec 100644 (file)
@@ -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;
        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;
 
        /* Short cut */
        ksession = session->kernel_session;
+       usess = session->ust_session;
 
        if (!session->enabled)
                return LTTCOMM_UST_START_FAIL;
 
        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);
        }
 
                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) {
                if (ret < 0) {
-                       ret = LTTCOMM_KERN_STOP_FAIL;
+                       ret = LTTCOMM_UST_START_FAIL;
                        goto error;
                }
                        goto error;
                }
-
-               ustctl_wait_quiescent(usess->sock);
        }
        }
-#endif
 
        ret = LTTCOMM_OK;
 
 
        ret = LTTCOMM_OK;
 
index 46c3dfdc12442247274801d26a3dac72f58bbf95..3547679f8bc8dbe1381aae36f46a54a7f3933932 100644 (file)
@@ -1122,6 +1122,10 @@ int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app)
                goto error_rcu_unlock;
        }
 
                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;
        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;
        }
        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) {
        /* 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;
 }
 
        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.
  */
 /*
  * Start tracing for the UST session.
  */
@@ -1211,6 +1270,32 @@ int ust_app_start_trace_all(struct ltt_ust_session *usess)
        return 0;
 }
 
        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.
  */
 /*
  * Add channels/events from UST global domain to registered apps at sock.
  */
index f8b0c6c6db604ff12d07e3b1307e3a901057130b..3159ba5cbded77d91170b5cb834eab2c900f1e04 100644 (file)
@@ -78,6 +78,8 @@ struct ust_app_channel {
 
 struct ust_app_session {
        int enabled;
 
 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;
        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);
                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_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);
 
 int ust_app_list_events(struct lttng_event **events);
 void ust_app_global_update(struct ltt_ust_session *usess, int sock);
 
This page took 0.043747 seconds and 4 git commands to generate.