*/
#define UUID_STR_LEN 37
+/* Trace type for lttng_trace.
+ */
+enum lttng_trace_type {
+ KERNEL, USERSPACE,
+};
+
/* Simple structure representing a session.
*/
struct lttng_session {
char uuid[UUID_STR_LEN];
};
+/* Simple trace representation.
+ */
+struct lttng_trace {
+ char name[NAME_MAX];
+ pid_t pid;
+ enum lttng_trace_type type;
+};
+
extern int lttng_create_session(char *name, uuid_t *session_id);
extern int lttng_destroy_session(uuid_t *uuid);
extern int lttng_connect_sessiond(void);
extern const char *lttng_get_readable_code(int code);
extern int lttng_ust_list_apps(pid_t **pids);
extern int lttng_list_sessions(struct lttng_session **sessions);
+extern int lttng_list_traces(uuid_t *uuid, struct lttng_trace **traces);
extern void lttng_set_current_session_uuid(char *uuid);
extern int lttng_ust_create_trace(pid_t pid);
extern int lttng_ust_start_trace(pid_t pid);
return ret / sizeof(pid_t);
}
+/*
+ * lttng_list_traces
+ *
+ * Ask the session daemon for all traces (kernel and ust)
+ * for the session identified by uuid.
+ *
+ * Return the number of traces.
+ */
+int lttng_list_traces(uuid_t *uuid, struct lttng_trace **traces)
+{
+ int ret;
+
+ uuid_copy(lsm.session_id, *uuid);
+
+ ret = ask_sessiond(LTTNG_LIST_TRACES, (void **) traces);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return ret / sizeof(struct lttng_trace);
+}
+
/*
* lttng_create_session
*
LTTNG_GET_SUBBUF_NUM_SIZE,
LTTNG_LIST_MARKERS,
LTTNG_LIST_SESSIONS,
+ LTTNG_LIST_TRACES,
LTTNG_LIST_TRACE_EVENTS,
LTTNG_SETUP_TRACE,
LTTNG_SET_SOCK_PATH,
/* Init */
trace->pid = pid;
trace->shmid = 0;
+ /* NOTE: to be removed. Trace name will no longer be
+ * required for LTTng userspace tracer. For now, we set it
+ * to 'auto' for API compliance.
+ */
+ snprintf(trace->name, 5, "auto");
/* Connect to app using ustctl API */
sock = connect_app(pid);
goto error;
}
- ret = ustctl_create_trace(sock, "auto");
+ ret = ustctl_create_trace(sock, trace->name);
if (ret < 0) {
ret = LTTCOMM_CREATE_FAIL;
goto error;
/* Check if current session is valid */
if (current_session) {
cds_list_add(&trace->list, ¤t_session->ust_traces);
+ current_session->ust_trace_count++;
}
error:
/* No auxiliary data so only send the llm struct. */
goto end;
}
+ case LTTNG_LIST_TRACES:
+ {
+ unsigned int trace_count = get_trace_count_per_session(current_session);
+
+ if (trace_count == 0) {
+ ret = LTTCOMM_NO_TRACE;
+ goto end;
+ }
+
+ buf_size = setup_data_buffer(&send_buf,
+ sizeof(struct lttng_trace) * trace_count, &llm);
+ if (buf_size < 0) {
+ ret = LTTCOMM_FATAL;
+ goto end;
+ }
+
+ get_traces_per_session(current_session, (struct lttng_trace *)(send_buf + header_size));
+ break;
+ }
case UST_CREATE_TRACE:
{
ret = ust_create_trace(lsm->pid);
* NO consumer attach to that session yet.
*/
new_session->ust_consumer = 0;
- new_session->lttng_consumer = 0;
+ new_session->kernel_consumer = 0;
/* Init list */
CDS_INIT_LIST_HEAD(&new_session->ust_traces);
- CDS_INIT_LIST_HEAD(&new_session->lttng_traces);
+ CDS_INIT_LIST_HEAD(&new_session->kernel_traces);
+
+ /* Set trace list counter */
+ new_session->ust_trace_count = 0;
+ new_session->kern_trace_count = 0;
/* Add new session to the global session list */
add_session_list(new_session);
struct cds_list_head list;
uuid_t uuid;
struct cds_list_head ust_traces;
- struct cds_list_head lttng_traces;
+ struct cds_list_head kernel_traces;
+ unsigned int ust_trace_count;
+ unsigned int kern_trace_count;
pid_t ust_consumer;
- pid_t lttng_consumer;
+ pid_t kernel_consumer;
};
/* Prototypes */
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <urcu/list.h>
#include "lttngerr.h"
return NULL;
}
+/*
+ * get_trace_count_per_session
+ *
+ * Return the total count of traces (ust and kernel)
+ * for the specified session.
+ */
+int get_trace_count_per_session(struct ltt_session *session)
+{
+ return session->ust_trace_count + session->kern_trace_count;
+}
+
+/*
+ * get_traces_per_session
+ *
+ * Fill the lttng_trace array of all the
+ * available trace of the session.
+ */
+void get_traces_per_session(struct ltt_session *session, struct lttng_trace *traces)
+{
+ int i = 0;
+ struct ltt_ust_trace *ust_iter;
+ struct ltt_kernel_trace *kern_iter;
+ struct lttng_trace trace;
+
+ DBG("Getting userspace traces for session %s", session->name);
+
+ /* Getting userspace traces */
+ cds_list_for_each_entry(ust_iter, &session->ust_traces, list) {
+ trace.type = USERSPACE;
+ trace.pid = ust_iter->pid;
+ strncpy(trace.name, ust_iter->name, sizeof(trace.name));
+ trace.name[sizeof(trace.name) - 1] = '\0';
+ memcpy(&traces[i], &trace, sizeof(trace));
+ memset(&trace, 0, sizeof(trace));
+ i++;
+ }
+
+ DBG("Getting kernel traces for session %s", session->name);
+
+ /* Getting kernel traces */
+ cds_list_for_each_entry(kern_iter, &session->kernel_traces, list) {
+ trace.type = KERNEL;
+ strncpy(trace.name, kern_iter->name, sizeof(trace.name));
+ trace.name[sizeof(trace.name) - 1] = '\0';
+ memcpy(&traces[i], &trace, sizeof(trace));
+ memset(&trace, 0, sizeof(trace));
+ i++;
+ }
+}
#include "session.h"
/* LTTng trace representation */
-struct ltt_lttng_trace {
+struct ltt_kernel_trace {
struct cds_list_head list;
- char trace_name[NAME_MAX];
+ char name[NAME_MAX];
struct cds_list_head marker_list;
};
/* UST trace representation */
struct ltt_ust_trace {
struct cds_list_head list;
+ char name[NAME_MAX];
int shmid;
pid_t pid;
struct cds_list_head markers;
};
struct ltt_ust_trace *find_session_ust_trace_by_pid(struct ltt_session *session, pid_t pid);
+int get_trace_count_per_session(struct ltt_session *session);
+void get_traces_per_session(struct ltt_session *session, struct lttng_trace *traces);
#endif /* _LTT_TRACE_H */
static int process_client_opt(void);
static int process_opt_list_apps(void);
static int process_opt_list_sessions(void);
+static int process_opt_list_traces(void);
static int process_opt_create_session(void);
static void sighandler(int sig);
static int set_signal_handler(void);
}
}
+ if (opt_list_traces) {
+ ret = process_opt_list_traces();
+ if (ret < 0) {
+ goto end;
+ }
+ }
+
if (opt_create_session != NULL) {
ret = process_opt_create_session();
if (ret < 0) {
return ret;
}
+/*
+ * process_opt_list_traces
+ *
+ * Get list of all traces for a specific session uuid.
+ */
+static int process_opt_list_traces(void)
+{
+ int ret, i;
+ uuid_t uuid;
+ struct lttng_trace *traces;
+
+ uuid_parse(opt_session_uuid, uuid);
+ ret = lttng_list_traces(&uuid, &traces);
+ if (ret < 0) {
+ goto error;
+ }
+
+ MSG("Userspace traces:");
+ for (i = 0; i < ret; i++) {
+ if (traces[i].type == USERSPACE) {
+ MSG("\t%d) %s (pid: %d)", i, traces[i].name, traces[i].pid);
+ } else {
+ break;
+ }
+ }
+
+ MSG("Kernel traces:");
+ for (;i < ret; i++) {
+ if (traces[i].type == KERNEL) {
+ MSG("\t%d) %s", i, traces[i].name);
+ }
+ }
+
+ free(traces);
+
+error:
+ return ret;
+}
+
/*
* process_opt_create_session
*
static int validate_options(void)
{
if ((opt_session_uuid == NULL) &&
- (opt_create_trace || opt_start_trace)) {
- ERR("Can't act on trace without a session ID.\nPlease specify using --session UUID");
+ (opt_create_trace || opt_start_trace || opt_list_traces)) {
+ ERR("You need to specify a session UUID.\nPlease use --session UUID to do so.");
goto error;
}
extern int opt_list_apps;
extern int opt_no_sessiond;
extern int opt_list_session;
+extern int opt_list_traces;
extern pid_t opt_create_trace;
extern pid_t opt_start_trace;
int opt_list_apps = 0;
int opt_no_sessiond = 0;
int opt_list_session = 0;
+int opt_list_traces = 0;
pid_t opt_create_trace = 0;
pid_t opt_start_trace = 0;
{"kernel", 0, POPT_ARG_VAL, &opt_trace_kernel, 1, 0, 0},
{"list-apps", 'L', POPT_ARG_VAL, &opt_list_apps, 1, 0, 0},
{"list-sessions", 'l', POPT_ARG_VAL, &opt_list_session, 1, 0, 0},
+ {"list-traces", 't', POPT_ARG_VAL, &opt_list_traces, 1, 0, 0},
{"no-kernel", 0, POPT_ARG_VAL, &opt_trace_kernel, 0, 0, 0},
{"no-sessiond", 0, POPT_ARG_VAL, &opt_no_sessiond, 1, 0, 0},
{"quiet", 'q', POPT_ARG_VAL, &opt_quiet, 1, 0, 0},
//fprintf(ofp, " --kernel Enable kernel tracing\n");
//fprintf(ofp, " --no-kernel Disable kernel tracing\n");
fprintf(ofp, " -L, --list-apps List traceable UST applications\n");
+ fprintf(ofp, " -t, --list-traces List session's traces. Use -s to specify the session\n");
fprintf(ofp, " -C, --create-trace PID Create trace for PID\n");
fprintf(ofp, " --start PID Start trace for PID\n");
fprintf(ofp, "\n");