X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fmain.c;h=a970012c7fde9fc90464adfd2520add2e6a3a903;hb=f3dd7ce78597e2d8b002fcc9536aa6016d1b039f;hp=fdc53760330d6d12766dc9ed370b1a1b641f5290;hpb=8bdee6e2bac74a577147046126628ff3b1b34930;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index fdc537603..a970012c7 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -18,6 +18,7 @@ */ #define _GNU_SOURCE +#define _LGPL_SOURCE #include #include #include @@ -67,9 +68,10 @@ #include "health-sessiond.h" #include "testpoint.h" #include "ust-thread.h" -#include "jul-thread.h" +#include "agent-thread.h" #include "save.h" #include "load-session-thread.h" +#include "syscall.h" #define CONSUMERD_FILE "lttng-consumerd" @@ -153,10 +155,11 @@ static const struct option long_options[] = { { "verbose-consumer", 0, 0, 'Z' }, { "no-kernel", 0, 0, 'N' }, { "pidfile", 1, 0, 'p' }, - { "jul-tcp-port", 1, 0, 'J' }, + { "agent-tcp-port", 1, 0, 'J' }, { "config", 1, 0, 'f' }, { "load", 1, 0, 'l' }, { "kmod-probes", 1, 0, 'P' }, + { "extra-kmod-probes", 1, 0, 'e' }, { NULL, 0, 0, 0 } }; @@ -204,7 +207,7 @@ static pthread_t kernel_thread; static pthread_t dispatch_thread; static pthread_t health_thread; static pthread_t ht_cleanup_thread; -static pthread_t jul_reg_thread; +static pthread_t agent_reg_thread; static pthread_t load_session_thread; /* @@ -289,8 +292,8 @@ long page_size; /* Application health monitoring */ struct health_app *health_sessiond; -/* JUL TCP port for registration. Used by the JUL thread. */ -unsigned int jul_tcp_port = DEFAULT_JUL_TCP_PORT; +/* Agent TCP port for registration. Used by the agent thread. */ +unsigned int agent_tcp_port = DEFAULT_AGENT_TCP_PORT; /* Am I root or not. */ int is_root; /* Set to 1 if the daemon is running as root */ @@ -571,7 +574,7 @@ static void cleanup(void) (void) unlink(path); snprintf(path, PATH_MAX, "%s/%s", rundir, - DEFAULT_LTTNG_SESSIOND_JULPORT_FILE); + DEFAULT_LTTNG_SESSIOND_AGENTPORT_FILE); DBG("Removing %s", path); (void) unlink(path); @@ -641,6 +644,7 @@ static void cleanup(void) } DBG("Unloading kernel modules"); modprobe_remove_lttng_all(); + free(syscall_table); } close_consumer_sockets(); @@ -1113,7 +1117,7 @@ static void signal_consumer_condition(struct consumer_data *data, int state) */ static void *thread_manage_consumer(void *data) { - int sock = -1, i, ret, pollfd, err = -1; + int sock = -1, i, ret, pollfd, err = -1, should_quit = 0; uint32_t revents, nb_fd; enum lttcomm_return_code code; struct lttng_poll_event events; @@ -1271,6 +1275,15 @@ restart: /* Infinite blocking call, waiting for transmission */ restart_poll: while (1) { + health_code_update(); + + /* Exit the thread because the thread quit pipe has been triggered. */ + if (should_quit) { + /* Not a health error. */ + err = 0; + goto exit; + } + health_poll_entry(); ret = lttng_poll_wait(&events, -1); health_poll_exit(); @@ -1293,12 +1306,12 @@ restart_poll: health_code_update(); - /* Thread quit pipe has been closed. Killing thread. */ - ret = sessiond_check_thread_quit_pipe(pollfd, revents); - if (ret) { - err = 0; - goto exit; - } + /* + * Thread quit pipe has been triggered, flag that we should stop + * but continue the current loop to handle potential data from + * consumer. + */ + should_quit = sessiond_check_thread_quit_pipe(pollfd, revents); if (pollfd == sock) { /* Event on the consumerd socket */ @@ -1327,11 +1340,8 @@ restart_poll: ERR("Handling metadata request"); goto error; } - break; - } else { - ERR("Unknown pollfd"); - goto error; } + /* No need for an else branch all FDs are tested prior. */ } health_code_update(); } @@ -2593,6 +2603,8 @@ static int copy_session_consumer(int domain, struct ltt_session *session) dir_name = DEFAULT_KERNEL_TRACE_DIR; break; case LTTNG_DOMAIN_JUL: + case LTTNG_DOMAIN_LOG4J: + case LTTNG_DOMAIN_PYTHON: case LTTNG_DOMAIN_UST: DBG3("Copying tracing session consumer output in UST session"); if (session->ust_session->consumer) { @@ -2637,6 +2649,8 @@ static int create_ust_session(struct ltt_session *session, switch (domain->type) { case LTTNG_DOMAIN_JUL: + case LTTNG_DOMAIN_LOG4J: + case LTTNG_DOMAIN_PYTHON: case LTTNG_DOMAIN_UST: break; default: @@ -2823,6 +2837,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, case LTTNG_LIST_DOMAINS: case LTTNG_LIST_CHANNELS: case LTTNG_LIST_EVENTS: + case LTTNG_LIST_SYSCALLS: break; default: /* Setup lttng message with no payload */ @@ -2841,6 +2856,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, case LTTNG_CALIBRATE: case LTTNG_LIST_SESSIONS: case LTTNG_LIST_TRACEPOINTS: + case LTTNG_LIST_SYSCALLS: case LTTNG_LIST_TRACEPOINT_FIELDS: case LTTNG_SAVE_SESSION: need_tracing_session = 0; @@ -2873,7 +2889,6 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, switch (cmd_ctx->lsm->cmd_type) { case LTTNG_DISABLE_CHANNEL: case LTTNG_DISABLE_EVENT: - case LTTNG_DISABLE_ALL_EVENT: switch (cmd_ctx->lsm->domain.type) { case LTTNG_DOMAIN_KERNEL: if (!cmd_ctx->session->kernel_session) { @@ -2882,6 +2897,8 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, } break; case LTTNG_DOMAIN_JUL: + case LTTNG_DOMAIN_LOG4J: + case LTTNG_DOMAIN_PYTHON: case LTTNG_DOMAIN_UST: if (!cmd_ctx->session->ust_session) { ret = LTTNG_ERR_NO_CHANNEL; @@ -2963,6 +2980,8 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, break; case LTTNG_DOMAIN_JUL: + case LTTNG_DOMAIN_LOG4J: + case LTTNG_DOMAIN_PYTHON: case LTTNG_DOMAIN_UST: { if (!ust_app_supported()) { @@ -3056,6 +3075,8 @@ skip_domain: cmd_ctx->lsm->cmd_type == LTTNG_STOP_TRACE) { switch (cmd_ctx->lsm->domain.type) { case LTTNG_DOMAIN_JUL: + case LTTNG_DOMAIN_LOG4J: + case LTTNG_DOMAIN_PYTHON: case LTTNG_DOMAIN_UST: if (uatomic_read(&ust_consumerd_state) != CONSUMER_STARTED) { ret = LTTNG_ERR_NO_USTCONSUMERD; @@ -3116,17 +3137,11 @@ skip_domain: } case LTTNG_DISABLE_EVENT: { + /* FIXME: passing packed structure to non-packed pointer */ + /* TODO: handle filter */ ret = cmd_disable_event(cmd_ctx->session, cmd_ctx->lsm->domain.type, cmd_ctx->lsm->u.disable.channel_name, - cmd_ctx->lsm->u.disable.name); - break; - } - case LTTNG_DISABLE_ALL_EVENT: - { - DBG("Disabling all events"); - - ret = cmd_disable_event_all(cmd_ctx->session, cmd_ctx->lsm->domain.type, - cmd_ctx->lsm->u.disable.channel_name); + &cmd_ctx->lsm->u.disable.event); break; } case LTTNG_ENABLE_CHANNEL: @@ -3203,12 +3218,14 @@ skip_domain: if (bytecode_len > LTTNG_FILTER_MAX_LEN) { ret = LTTNG_ERR_FILTER_INVAL; + free(filter_expression); free(exclusion); goto error; } bytecode = zmalloc(bytecode_len); if (!bytecode) { + free(filter_expression); free(exclusion); ret = LTTNG_ERR_FILTER_NOMEM; goto error; @@ -3220,6 +3237,7 @@ skip_domain: if (ret <= 0) { DBG("Nothing recv() from client car len data... continuing"); *sock_error = 1; + free(filter_expression); free(bytecode); free(exclusion); ret = LTTNG_ERR_FILTER_INVAL; @@ -3227,6 +3245,7 @@ skip_domain: } if ((bytecode->len + sizeof(*bytecode)) != bytecode_len) { + free(filter_expression); free(bytecode); free(exclusion); ret = LTTNG_ERR_FILTER_INVAL; @@ -3241,16 +3260,6 @@ skip_domain: kernel_poll_pipe[1]); break; } - case LTTNG_ENABLE_ALL_EVENT: - { - DBG("Enabling all events"); - - ret = cmd_enable_event_all(cmd_ctx->session, &cmd_ctx->lsm->domain, - cmd_ctx->lsm->u.enable.channel_name, - cmd_ctx->lsm->u.enable.event.type, NULL, NULL, - kernel_poll_pipe[1]); - break; - } case LTTNG_LIST_TRACEPOINTS: { struct lttng_event *events; @@ -3319,6 +3328,37 @@ skip_domain: ret = LTTNG_OK; break; } + case LTTNG_LIST_SYSCALLS: + { + struct lttng_event *events; + ssize_t nb_events; + + nb_events = cmd_list_syscalls(&events); + if (nb_events < 0) { + /* Return value is a negative lttng_error_code. */ + ret = -nb_events; + goto error; + } + + /* + * Setup lttng message with payload size set to the event list size in + * bytes and then copy list into the llm payload. + */ + ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_event) * nb_events); + if (ret < 0) { + free(events); + goto setup_error; + } + + /* Copy event list into message payload */ + memcpy(cmd_ctx->llm->payload, events, + sizeof(struct lttng_event) * nb_events); + + free(events); + + ret = LTTNG_OK; + break; + } case LTTNG_SET_CONSUMER_URI: { size_t nb_uri, len; @@ -3439,7 +3479,7 @@ skip_domain: case LTTNG_LIST_DOMAINS: { ssize_t nb_dom; - struct lttng_domain *domains; + struct lttng_domain *domains = NULL; nb_dom = cmd_list_domains(cmd_ctx->session, &domains); if (nb_dom < 0) { @@ -3466,7 +3506,7 @@ skip_domain: case LTTNG_LIST_CHANNELS: { int nb_chan; - struct lttng_channel *channels; + struct lttng_channel *channels = NULL; nb_chan = cmd_list_channels(cmd_ctx->lsm->domain.type, cmd_ctx->session, &channels); @@ -4205,10 +4245,11 @@ static void usage(void) fprintf(stderr, " -p, --pidfile FILE Write a pid to FILE name overriding the default value.\n"); fprintf(stderr, " --verbose-consumer Verbose mode for consumer. Activate DBG() macro.\n"); fprintf(stderr, " --no-kernel Disable kernel tracer\n"); - fprintf(stderr, " --jul-tcp-port JUL application registration TCP port\n"); - fprintf(stderr, " -f --config Load daemon configuration file\n"); + fprintf(stderr, " --agent-tcp-port Agent registration TCP port\n"); + fprintf(stderr, " -f --config PATH Load daemon configuration file\n"); fprintf(stderr, " -l --load PATH Load session configuration\n"); fprintf(stderr, " --kmod-probes Specify kernel module probes to load\n"); + fprintf(stderr, " --extra-kmod-probes Specify extra kernel module probes to load\n"); } /* @@ -4221,6 +4262,17 @@ static int set_option(int opt, const char *arg, const char *optname) { int ret = 0; + if (arg && arg[0] == '\0') { + /* + * This only happens if the value is read from daemon config + * file. This means the option requires an argument and the + * configuration file contains a line such as: + * my_option = + */ + ret = -EINVAL; + goto end; + } + switch (opt) { case 0: fprintf(stderr, "option %s", optname); @@ -4361,22 +4413,22 @@ static int set_option(int opt, const char *arg, const char *optname) ret = -ENOMEM; } break; - case 'J': /* JUL TCP port. */ + case 'J': /* Agent TCP port. */ { unsigned long v; errno = 0; v = strtoul(arg, NULL, 0); if (errno != 0 || !isdigit(arg[0])) { - ERR("Wrong value in --jul-tcp-port parameter: %s", arg); + ERR("Wrong value in --agent-tcp-port parameter: %s", arg); return -1; } if (v == 0 || v >= 65535) { - ERR("Port overflow in --jul-tcp-port parameter: %s", arg); + ERR("Port overflow in --agent-tcp-port parameter: %s", arg); return -1; } - jul_tcp_port = (uint32_t) v; - DBG3("JUL TCP port set to non default: %u", jul_tcp_port); + agent_tcp_port = (uint32_t) v; + DBG3("Agent TCP port set to non default: %u", agent_tcp_port); break; } case 'l': @@ -4395,6 +4447,14 @@ static int set_option(int opt, const char *arg, const char *optname) ret = -ENOMEM; } break; + case 'e': + free(kmod_extra_probes_list); + kmod_extra_probes_list = strdup(arg); + if (!kmod_extra_probes_list) { + perror("strdup"); + ret = -ENOMEM; + } + break; case 'f': /* This is handled in set_options() thus silent break. */ break; @@ -4404,6 +4464,23 @@ static int set_option(int opt, const char *arg, const char *optname) ret = -1; } +end: + if (ret == -EINVAL) { + const char *opt_name = "unknown"; + int i; + + for (i = 0; i < sizeof(long_options) / sizeof(struct option); + i++) { + if (opt == long_options[i].val) { + opt_name = long_options[i].name; + break; + } + } + + WARN("Invalid argument provided for option \"%s\", using default value.", + opt_name); + } + return ret; } @@ -4916,9 +4993,9 @@ error: } /* - * Write JUL TCP port using the rundir. + * Write agent TCP port using the rundir. */ -static void write_julport(void) +static void write_agent_port(void) { int ret; char path[PATH_MAX]; @@ -4926,18 +5003,18 @@ static void write_julport(void) assert(rundir); ret = snprintf(path, sizeof(path), "%s/" - DEFAULT_LTTNG_SESSIOND_JULPORT_FILE, rundir); + DEFAULT_LTTNG_SESSIOND_AGENTPORT_FILE, rundir); if (ret < 0) { - PERROR("snprintf julport path"); + PERROR("snprintf agent port path"); goto error; } /* - * Create TCP JUL port file in rundir. Return value is of no importance. + * Create TCP agent port file in rundir. Return value is of no importance. * The execution will continue even though we are not able to write the * file. */ - (void) utils_create_pid_file(jul_tcp_port, path); + (void) utils_create_pid_file(agent_tcp_port, path); error: return; @@ -5034,6 +5111,10 @@ int main(int argc, char **argv) if (is_root) { rundir = strdup(DEFAULT_LTTNG_RUNDIR); + if (!rundir) { + ret = -ENOMEM; + goto error; + } /* Create global run dir with root access */ ret = create_lttng_rundir(rundir); @@ -5174,8 +5255,8 @@ int main(int argc, char **argv) */ ust_app_ht_alloc(); - /* Initialize JUL domain subsystem. */ - if ((ret = jul_init()) < 0) { + /* Initialize agent domain subsystem. */ + if ((ret = agent_setup()) < 0) { /* ENOMEM at this point. */ goto error; } @@ -5197,6 +5278,13 @@ int main(int argc, char **argv) /* Setup kernel tracer */ if (!opt_no_kernel) { init_kernel_tracer(); + if (kernel_tracer_fd >= 0) { + ret = syscall_init_table(); + if (ret < 0) { + ERR("Unable to populate syscall table. Syscall tracing" + " won't work for this session daemon."); + } + } } /* Set ulimit for open files */ @@ -5279,7 +5367,7 @@ int main(int argc, char **argv) } write_pidfile(); - write_julport(); + write_agent_port(); /* Initialize communication library */ lttcomm_init(); @@ -5357,12 +5445,12 @@ int main(int argc, char **argv) goto exit_apps_notify; } - /* Create JUL registration thread. */ - ret = pthread_create(&jul_reg_thread, NULL, - jul_thread_manage_registration, (void *) NULL); + /* Create agent registration thread. */ + ret = pthread_create(&agent_reg_thread, NULL, + agent_thread_manage_registration, (void *) NULL); if (ret != 0) { - PERROR("pthread_create JUL"); - goto exit_jul_reg; + PERROR("pthread_create agent"); + goto exit_agent_reg; } /* Don't start this thread if kernel tracing is not requested nor root */ @@ -5388,13 +5476,13 @@ int main(int argc, char **argv) } exit_kernel: - ret = pthread_join(jul_reg_thread, &status); + ret = pthread_join(agent_reg_thread, &status); if (ret != 0) { - PERROR("pthread_join JUL"); + PERROR("pthread_join agent"); goto error; /* join error, exit without cleanup */ } -exit_jul_reg: +exit_agent_reg: ret = pthread_join(apps_notify_thread, &status); if (ret != 0) { PERROR("pthread_join apps notify");