/* * Adding channel using the lttng API. */ static int enable_channel(char *session_name) { int ret = CMD_SUCCESS, warn = 0, error = 0, success = 0; char *channel_name; struct lttng_domain dom; memset(&dom, 0, sizeof(dom)); /* Create lttng domain */ if (opt_kernel) { dom.type = LTTNG_DOMAIN_KERNEL; dom.buf_type = LTTNG_BUFFER_GLOBAL; if (opt_buffer_uid || opt_buffer_pid) { ERR("Buffer type not supported for domain -k"); ret = CMD_ERROR; goto error; } } else if (opt_userspace) { dom.type = LTTNG_DOMAIN_UST; if (opt_buffer_pid) { dom.buf_type = LTTNG_BUFFER_PER_PID; } else { if (opt_buffer_global) { ERR("Buffer type not supported for domain -u"); ret = CMD_ERROR; goto error; } dom.buf_type = LTTNG_BUFFER_PER_UID; } } else { print_missing_domain(); ret = CMD_ERROR; goto error; } set_default_attr(&dom); if (chan.attr.tracefile_size == 0 && chan.attr.tracefile_count) { ERR("Missing option --tracefile-size. " "A file count without a size won't do anything."); ret = CMD_ERROR; goto error; } if ((chan.attr.tracefile_size > 0) && (chan.attr.tracefile_size < chan.attr.subbuf_size)) { WARN("Tracefile size rounded up from (%" PRIu64 ") to subbuffer size (%" PRIu64 ")", chan.attr.tracefile_size, chan.attr.subbuf_size); chan.attr.tracefile_size = chan.attr.subbuf_size; } /* Setting channel output */ if (opt_output) { if (!strncmp(output_mmap, opt_output, strlen(output_mmap))) { chan.attr.output = LTTNG_EVENT_MMAP; } else if (!strncmp(output_splice, opt_output, strlen(output_splice))) { chan.attr.output = LTTNG_EVENT_SPLICE; } else { ERR("Unknown output type %s. Possible values are: %s, %s\n", opt_output, output_mmap, output_splice); usage(stderr); ret = CMD_ERROR; goto error; } } handle = lttng_create_handle(session_name, &dom); if (handle == NULL) { ret = -1; goto error; } /* Mi open channels element */ if (lttng_opt_mi) { assert(writer); ret = mi_lttng_channels_open(writer); if (ret) { ret = CMD_ERROR; goto error; } } /* Strip channel list (format: chan1,chan2,...) */ channel_name = strtok(opt_channels, ","); while (channel_name != NULL) { /* Copy channel name and normalize it */ strncpy(chan.name, channel_name, NAME_MAX); chan.name[NAME_MAX - 1] = '\0'; DBG("Enabling channel %s", channel_name); ret = lttng_enable_channel(handle, &chan); if (ret < 0) { success = 0; switch (-ret) { case LTTNG_ERR_KERN_CHAN_EXIST: case LTTNG_ERR_UST_CHAN_EXIST: case LTTNG_ERR_CHAN_EXIST: WARN("Channel %s: %s (session %s)", channel_name, lttng_strerror(ret), session_name); warn = 1; break; default: ERR("Channel %s: %s (session %s)", channel_name, lttng_strerror(ret), session_name); error = 1; break; } } else { MSG("%s channel %s enabled for session %s", get_domain_str(dom.type), channel_name, session_name); success = 1; } if (lttng_opt_mi) { /* Mi print the channel element and leave it open */ ret = mi_lttng_channel(writer, &chan, 1); if (ret) { ret = CMD_ERROR; goto error; } /* Individual Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto error; } /* Close channel element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto error; } } /* Next channel */ channel_name = strtok(NULL, ","); } if (lttng_opt_mi) { /* Close channels element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto error; } } ret = CMD_SUCCESS; error: /* If more important error happen bypass the warning */ if (!ret && warn) { ret = CMD_WARNING; } /* If more important error happen bypass the warning */ if (!ret && error) { ret = CMD_ERROR; } lttng_destroy_handle(handle); return ret; }
/* * Adding channel using the lttng API. */ static int enable_channel(char *session_name) { int ret = CMD_SUCCESS, warn = 0; char *channel_name; struct lttng_domain dom; memset(&dom, 0, sizeof(dom)); /* Create lttng domain */ if (opt_kernel) { dom.type = LTTNG_DOMAIN_KERNEL; dom.buf_type = LTTNG_BUFFER_GLOBAL; if (opt_buffer_uid || opt_buffer_pid) { ERR("Buffer type not supported for domain -k"); ret = CMD_ERROR; goto error; } } else if (opt_userspace) { dom.type = LTTNG_DOMAIN_UST; if (opt_buffer_uid) { dom.buf_type = LTTNG_BUFFER_PER_UID; } else { if (opt_buffer_global) { ERR("Buffer type not supported for domain -u"); ret = CMD_ERROR; goto error; } dom.buf_type = LTTNG_BUFFER_PER_PID; } } else { ERR("Please specify a tracer (-k/--kernel or -u/--userspace)"); ret = CMD_ERROR; goto error; } set_default_attr(&dom); if (chan.attr.tracefile_size == 0 && chan.attr.tracefile_count) { ERR("Missing option --tracefile-size. " "A file count without a size won't do anything."); ret = CMD_ERROR; goto error; } if ((chan.attr.tracefile_size > 0) && (chan.attr.tracefile_size < chan.attr.subbuf_size)) { WARN("Tracefile size rounded up from (%" PRIu64 ") to subbuffer size (%" PRIu64 ")", chan.attr.tracefile_size, chan.attr.subbuf_size); chan.attr.tracefile_size = chan.attr.subbuf_size; } /* Setting channel output */ if (opt_output) { if (!strncmp(output_mmap, opt_output, strlen(output_mmap))) { chan.attr.output = LTTNG_EVENT_MMAP; } else if (!strncmp(output_splice, opt_output, strlen(output_splice))) { chan.attr.output = LTTNG_EVENT_SPLICE; } else { ERR("Unknown output type %s. Possible values are: %s, %s\n", opt_output, output_mmap, output_splice); usage(stderr); ret = CMD_ERROR; goto error; } } handle = lttng_create_handle(session_name, &dom); if (handle == NULL) { ret = -1; goto error; } /* Strip channel list (format: chan1,chan2,...) */ channel_name = strtok(opt_channels, ","); while (channel_name != NULL) { /* Copy channel name and normalize it */ strncpy(chan.name, channel_name, NAME_MAX); chan.name[NAME_MAX - 1] = '\0'; DBG("Enabling channel %s", channel_name); ret = lttng_enable_channel(handle, &chan); if (ret < 0) { switch (-ret) { case LTTNG_ERR_KERN_CHAN_EXIST: case LTTNG_ERR_UST_CHAN_EXIST: WARN("Channel %s: %s (session %s)", channel_name, lttng_strerror(ret), session_name); goto error; default: ERR("Channel %s: %s (session %s)", channel_name, lttng_strerror(ret), session_name); break; } warn = 1; } else { MSG("%s channel %s enabled for session %s", opt_kernel ? "Kernel" : "UST", channel_name, session_name); } /* Next event */ channel_name = strtok(NULL, ","); } ret = CMD_SUCCESS; error: if (warn) { ret = CMD_WARNING; } lttng_destroy_handle(handle); return ret; }
/* * Adding channel using the lttng API. */ static int enable_channel(char *session_name) { struct lttng_channel *channel = NULL; int ret = CMD_SUCCESS, warn = 0, error = 0, success = 0; char *channel_name; struct lttng_domain dom; memset(&dom, 0, sizeof(dom)); /* Validate options. */ if (opt_kernel) { if (opt_blocking_timeout.set) { ERR("Retry timeout option not supported for kernel domain (-k)"); ret = CMD_ERROR; goto error; } } /* Create lttng domain */ if (opt_kernel) { dom.type = LTTNG_DOMAIN_KERNEL; dom.buf_type = LTTNG_BUFFER_GLOBAL; if (opt_buffer_uid || opt_buffer_pid) { ERR("Buffer type not supported for domain -k"); ret = CMD_ERROR; goto error; } } else if (opt_userspace) { dom.type = LTTNG_DOMAIN_UST; if (opt_buffer_pid) { dom.buf_type = LTTNG_BUFFER_PER_PID; } else { if (opt_buffer_global) { ERR("Buffer type not supported for domain -u"); ret = CMD_ERROR; goto error; } dom.buf_type = LTTNG_BUFFER_PER_UID; } } else { /* Checked by the caller. */ assert(0); } set_default_attr(&dom); if (chan_opts.attr.tracefile_size == 0 && chan_opts.attr.tracefile_count) { ERR("Missing option --tracefile-size. " "A file count without a size won't do anything."); ret = CMD_ERROR; goto error; } if ((chan_opts.attr.tracefile_size > 0) && (chan_opts.attr.tracefile_size < chan_opts.attr.subbuf_size)) { WARN("Tracefile size rounded up from (%" PRIu64 ") to subbuffer size (%" PRIu64 ")", chan_opts.attr.tracefile_size, chan_opts.attr.subbuf_size); chan_opts.attr.tracefile_size = chan_opts.attr.subbuf_size; } /* Setting channel output */ if (opt_output) { if (!strncmp(output_mmap, opt_output, strlen(output_mmap))) { chan_opts.attr.output = LTTNG_EVENT_MMAP; } else if (!strncmp(output_splice, opt_output, strlen(output_splice))) { chan_opts.attr.output = LTTNG_EVENT_SPLICE; } else { ERR("Unknown output type %s. Possible values are: %s, %s\n", opt_output, output_mmap, output_splice); ret = CMD_ERROR; goto error; } } handle = lttng_create_handle(session_name, &dom); if (handle == NULL) { ret = -1; goto error; } /* Mi open channels element */ if (lttng_opt_mi) { assert(writer); ret = mi_lttng_channels_open(writer); if (ret) { ret = CMD_ERROR; goto error; } } /* Strip channel list (format: chan1,chan2,...) */ channel_name = strtok(opt_channels, ","); while (channel_name != NULL) { void *extended_ptr; /* Validate channel name's length */ if (strlen(channel_name) >= sizeof(chan_opts.name)) { ERR("Channel name is too long (max. %zu characters)", sizeof(chan_opts.name) - 1); error = 1; goto skip_enable; } /* * A dynamically-allocated channel is used in order to allow * the configuration of extended attributes (post-2.9). */ channel = lttng_channel_create(&dom); if (!channel) { ERR("Unable to create channel object"); error = 1; goto error; } /* Copy channel name */ strcpy(channel->name, channel_name); channel->enabled = 1; extended_ptr = channel->attr.extended.ptr; memcpy(&channel->attr, &chan_opts.attr, sizeof(chan_opts.attr)); channel->attr.extended.ptr = extended_ptr; if (opt_monitor_timer.set) { ret = lttng_channel_set_monitor_timer_interval(channel, opt_monitor_timer.interval); if (ret) { ERR("Failed to set the channel's monitor timer interval"); error = 1; goto error; } } if (opt_blocking_timeout.set) { ret = lttng_channel_set_blocking_timeout(channel, opt_blocking_timeout.value); if (ret) { ERR("Failed to set the channel's blocking timeout"); error = 1; goto error; } } DBG("Enabling channel %s", channel_name); ret = lttng_enable_channel(handle, channel); if (ret < 0) { success = 0; switch (-ret) { case LTTNG_ERR_KERN_CHAN_EXIST: case LTTNG_ERR_UST_CHAN_EXIST: case LTTNG_ERR_CHAN_EXIST: WARN("Channel %s: %s (session %s)", channel_name, lttng_strerror(ret), session_name); warn = 1; break; case LTTNG_ERR_INVALID_CHANNEL_NAME: ERR("Invalid channel name: \"%s\". " "Channel names may not start with '.', and " "may not contain '/'.", channel_name); error = 1; break; default: ERR("Channel %s: %s (session %s)", channel_name, lttng_strerror(ret), session_name); error = 1; break; } } else { MSG("%s channel %s enabled for session %s", get_domain_str(dom.type), channel_name, session_name); success = 1; } skip_enable: if (lttng_opt_mi) { /* Mi print the channel element and leave it open */ ret = mi_lttng_channel(writer, channel, 1); if (ret) { ret = CMD_ERROR; goto error; } /* Individual Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto error; } /* Close channel element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto error; } } /* Next channel */ channel_name = strtok(NULL, ","); lttng_channel_destroy(channel); channel = NULL; } if (lttng_opt_mi) { /* Close channels element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto error; } } ret = CMD_SUCCESS; error: if (channel) { lttng_channel_destroy(channel); } /* If more important error happen bypass the warning */ if (!ret && warn) { ret = CMD_WARNING; } /* If more important error happen bypass the warning */ if (!ret && error) { ret = CMD_ERROR; } lttng_destroy_handle(handle); return ret; }