static
int _lttng_field_statedump(struct lttng_session *session,
const struct lttng_kernel_event_field *field,
- size_t nesting);
+ size_t nesting, const char **prev_field_name_p);
void synchronize_trace(void)
{
return ret;
}
-int lttng_event_enable(struct lttng_kernel_event_recorder *event_recorder)
+int lttng_event_enable(struct lttng_kernel_event_common *event)
{
- struct lttng_kernel_event_common *event = &event_recorder->parent;
int ret = 0;
mutex_lock(&sessions_mutex);
- if (event_recorder->chan->channel_type == METADATA_CHANNEL) {
- ret = -EPERM;
- goto end;
- }
- if (event->enabled) {
- ret = -EEXIST;
- goto end;
- }
- switch (event->priv->instrumentation) {
- case LTTNG_KERNEL_ABI_TRACEPOINT: /* Fall-through */
- case LTTNG_KERNEL_ABI_SYSCALL:
- ret = -EINVAL;
- break;
+ switch (event->type) {
+ case LTTNG_KERNEL_EVENT_TYPE_RECORDER:
+ {
+ struct lttng_kernel_event_recorder *event_recorder =
+ container_of(event, struct lttng_kernel_event_recorder, parent);
- case LTTNG_KERNEL_ABI_KPROBE: /* Fall-through */
- case LTTNG_KERNEL_ABI_UPROBE:
- WRITE_ONCE(event->enabled, 1);
+ if (event_recorder->chan->channel_type == METADATA_CHANNEL) {
+ ret = -EPERM;
+ goto end;
+ }
break;
-
- case LTTNG_KERNEL_ABI_KRETPROBE:
- ret = lttng_kretprobes_event_enable_state(&event_recorder->parent, 1);
+ }
+ case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
+ switch (event->priv->instrumentation) {
+ case LTTNG_KERNEL_ABI_KRETPROBE:
+ ret = -EINVAL;
+ goto end;
+ default:
+ break;
+ }
break;
-
- case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */
- case LTTNG_KERNEL_ABI_NOOP: /* Fall-through */
default:
- WARN_ON_ONCE(1);
- ret = -EINVAL;
+ break;
}
-end:
- mutex_unlock(&sessions_mutex);
- return ret;
-}
-
-int lttng_event_disable(struct lttng_kernel_event_recorder *event_recorder)
-{
- struct lttng_kernel_event_common *event = &event_recorder->parent;
- int ret = 0;
- mutex_lock(&sessions_mutex);
- if (event_recorder->chan->channel_type == METADATA_CHANNEL) {
- ret = -EPERM;
- goto end;
- }
- if (!event->enabled) {
+ if (event->enabled) {
ret = -EEXIST;
goto end;
}
case LTTNG_KERNEL_ABI_KPROBE: /* Fall-through */
case LTTNG_KERNEL_ABI_UPROBE:
- WRITE_ONCE(event->enabled, 0);
+ WRITE_ONCE(event->enabled, 1);
break;
case LTTNG_KERNEL_ABI_KRETPROBE:
-
- ret = lttng_kretprobes_event_enable_state(&event_recorder->parent, 0);
+ ret = lttng_kretprobes_event_enable_state(event, 1);
break;
case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */
return ret;
}
-int lttng_event_notifier_enable(struct lttng_kernel_event_notifier *event_notifier)
+int lttng_event_disable(struct lttng_kernel_event_common *event)
{
- struct lttng_kernel_event_common *event = &event_notifier->parent;
int ret = 0;
mutex_lock(&sessions_mutex);
- if (event->enabled) {
- ret = -EEXIST;
- goto end;
- }
- switch (event->priv->instrumentation) {
- case LTTNG_KERNEL_ABI_TRACEPOINT: /* Fall-through */
- case LTTNG_KERNEL_ABI_SYSCALL:
- ret = -EINVAL;
- break;
+ switch (event->type) {
+ case LTTNG_KERNEL_EVENT_TYPE_RECORDER:
+ {
+ struct lttng_kernel_event_recorder *event_recorder =
+ container_of(event, struct lttng_kernel_event_recorder, parent);
- case LTTNG_KERNEL_ABI_KPROBE: /* Fall-through */
- case LTTNG_KERNEL_ABI_UPROBE:
- WRITE_ONCE(event->enabled, 1);
+ if (event_recorder->chan->channel_type == METADATA_CHANNEL) {
+ ret = -EPERM;
+ goto end;
+ }
+ break;
+ }
+ case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
+ switch (event->priv->instrumentation) {
+ case LTTNG_KERNEL_ABI_KRETPROBE:
+ ret = -EINVAL;
+ goto end;
+ default:
+ break;
+ }
break;
-
- case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */
- case LTTNG_KERNEL_ABI_KRETPROBE: /* Fall-through */
- case LTTNG_KERNEL_ABI_NOOP: /* Fall-through */
default:
- WARN_ON_ONCE(1);
- ret = -EINVAL;
+ break;
}
-end:
- mutex_unlock(&sessions_mutex);
- return ret;
-}
-int lttng_event_notifier_disable(struct lttng_kernel_event_notifier *event_notifier)
-{
- struct lttng_kernel_event_common *event = &event_notifier->parent;
- int ret = 0;
-
- mutex_lock(&sessions_mutex);
if (!event->enabled) {
ret = -EEXIST;
goto end;
WRITE_ONCE(event->enabled, 0);
break;
+ case LTTNG_KERNEL_ABI_KRETPROBE:
+ ret = lttng_kretprobes_event_enable_state(event, 0);
+ break;
+
case LTTNG_KERNEL_ABI_FUNCTION: /* Fall-through */
- case LTTNG_KERNEL_ABI_KRETPROBE: /* Fall-through */
case LTTNG_KERNEL_ABI_NOOP: /* Fall-through */
default:
WARN_ON_ONCE(1);
event_recorder->parent.priv = &event_recorder_priv->parent;
event_recorder->parent.type = LTTNG_KERNEL_EVENT_TYPE_RECORDER;
+ event_recorder->parent.run_filter = lttng_kernel_interpret_event_filter;
event_recorder->chan = chan;
event_recorder->priv->id = chan->free_event_id++;
event_recorder->priv->parent.instrumentation = itype;
event_recorder_return->parent.priv = &event_recorder_return_priv->parent;
event_recorder_return->parent.type = LTTNG_KERNEL_EVENT_TYPE_RECORDER;
+ event_recorder_return->parent.run_filter = lttng_kernel_interpret_event_filter;
event_recorder_return->chan = chan;
event_recorder_return->priv->id = chan->free_event_id++;
event_recorder_return->priv->parent.instrumentation = itype;
INIT_LIST_HEAD(&event_notifier->priv->parent.filter_bytecode_runtime_head);
INIT_LIST_HEAD(&event_notifier->priv->parent.enablers_ref_head);
INIT_LIST_HEAD(&event_notifier->priv->capture_bytecode_runtime_head);
+ event_notifier->parent.run_filter = lttng_kernel_interpret_event_filter;
switch (itype) {
case LTTNG_KERNEL_ABI_TRACEPOINT:
int lttng_enabler_attach_filter_bytecode(struct lttng_enabler *enabler,
struct lttng_kernel_abi_filter_bytecode __user *bytecode)
{
- struct lttng_bytecode_node *bytecode_node;
+ struct lttng_kernel_bytecode_node *bytecode_node;
uint32_t bytecode_len;
int ret;
if (ret)
goto error_free;
- bytecode_node->type = LTTNG_BYTECODE_NODE_TYPE_FILTER;
+ bytecode_node->type = LTTNG_KERNEL_BYTECODE_TYPE_FILTER;
bytecode_node->enabler = enabler;
/* Enforce length based on allocated size */
bytecode_node->bc.len = bytecode_len;
static
void lttng_enabler_destroy(struct lttng_enabler *enabler)
{
- struct lttng_bytecode_node *filter_node, *tmp_filter_node;
+ struct lttng_kernel_bytecode_node *filter_node, *tmp_filter_node;
/* Destroy filter bytecode */
list_for_each_entry_safe(filter_node, tmp_filter_node,
struct lttng_event_notifier_enabler *event_notifier_enabler,
struct lttng_kernel_abi_capture_bytecode __user *bytecode)
{
- struct lttng_bytecode_node *bytecode_node;
+ struct lttng_kernel_bytecode_node *bytecode_node;
struct lttng_enabler *enabler =
lttng_event_notifier_enabler_as_enabler(event_notifier_enabler);
uint32_t bytecode_len;
if (ret)
goto error_free;
- bytecode_node->type = LTTNG_BYTECODE_NODE_TYPE_CAPTURE;
+ bytecode_node->type = LTTNG_KERNEL_BYTECODE_TYPE_CAPTURE;
bytecode_node->enabler = enabler;
/* Enforce length based on allocated size */
list_for_each_entry(event_recorder_priv, &session->events, node) {
struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
struct lttng_enabler_ref *enabler_ref;
- struct lttng_bytecode_runtime *runtime;
+ struct lttng_kernel_bytecode_runtime *runtime;
int enabled = 0, has_enablers_without_filter_bytecode = 0;
int nr_filters = 0;
/* Enable filters */
list_for_each_entry(runtime,
&event_recorder_priv->parent.filter_bytecode_runtime_head, node) {
- lttng_bytecode_filter_sync_state(runtime);
+ lttng_bytecode_sync_state(runtime);
nr_filters++;
}
WRITE_ONCE(event_recorder_priv->parent.pub->eval_filter,
list_for_each_entry(event_notifier_priv, &event_notifier_group->event_notifiers_head, node) {
struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
struct lttng_enabler_ref *enabler_ref;
- struct lttng_bytecode_runtime *runtime;
+ struct lttng_kernel_bytecode_runtime *runtime;
int enabled = 0, has_enablers_without_filter_bytecode = 0;
int nr_filters = 0, nr_captures = 0;
/* Enable filters */
list_for_each_entry(runtime,
&event_notifier_priv->parent.filter_bytecode_runtime_head, node) {
- lttng_bytecode_filter_sync_state(runtime);
+ lttng_bytecode_sync_state(runtime);
nr_filters++;
}
WRITE_ONCE(event_notifier_priv->parent.pub->eval_filter,
/* Enable captures */
list_for_each_entry(runtime,
&event_notifier_priv->capture_bytecode_runtime_head, node) {
- lttng_bytecode_capture_sync_state(runtime);
+ lttng_bytecode_sync_state(runtime);
nr_captures++;
}
WRITE_ONCE(event_notifier->eval_capture, !!nr_captures);
reserve_len = min_t(size_t,
stream->transport->ops.packet_avail_size(chan),
len);
- lib_ring_buffer_ctx_init(&ctx, chan, NULL, reserve_len,
- sizeof(char), -1);
+ lib_ring_buffer_ctx_init(&ctx, chan, reserve_len,
+ sizeof(char), NULL);
/*
* If reservation failed, return an error to the caller.
*/
- ret = stream->transport->ops.event_reserve(&ctx, 0);
+ ret = stream->transport->ops.event_reserve(&ctx);
if (ret != 0) {
printk(KERN_WARNING "LTTng: Metadata event reservation failed\n");
stream->coherent = false;
const struct lttng_kernel_type_struct *type,
size_t nesting)
{
+ const char *prev_field_name = NULL;
int ret;
uint32_t i, nr_fields;
unsigned int alignment;
const struct lttng_kernel_event_field *iter_field;
iter_field = type->fields[i];
- ret = _lttng_field_statedump(session, iter_field, nesting + 1);
+ ret = _lttng_field_statedump(session, iter_field, nesting + 1, &prev_field_name);
if (ret)
return ret;
}
static
int _lttng_variant_type_statedump(struct lttng_session *session,
const struct lttng_kernel_type_variant *type,
- size_t nesting)
+ size_t nesting,
+ const char *prev_field_name)
{
+ const char *tag_name;
int ret;
uint32_t i, nr_choices;
+ tag_name = type->tag_name;
+ if (!tag_name)
+ tag_name = prev_field_name;
+ if (!tag_name)
+ return -EINVAL;
/*
* CTF 1.8 does not allow expressing nonzero variant alignment in a nestable way.
*/
return ret;
ret = lttng_metadata_printf(session,
"variant <_%s> {\n",
- type->tag_name);
+ tag_name);
if (ret)
return ret;
nr_choices = type->nr_choices;
const struct lttng_kernel_event_field *iter_field;
iter_field = type->choices[i];
- ret = _lttng_field_statedump(session, iter_field, nesting + 1);
+ ret = _lttng_field_statedump(session, iter_field, nesting + 1, NULL);
if (ret)
return ret;
}
static
int _lttng_variant_field_statedump(struct lttng_session *session,
const struct lttng_kernel_event_field *field,
- size_t nesting)
+ size_t nesting,
+ const char *prev_field_name)
{
int ret;
ret = _lttng_variant_type_statedump(session,
- lttng_kernel_get_type_variant(field->type), nesting);
+ lttng_kernel_get_type_variant(field->type), nesting,
+ prev_field_name);
if (ret)
return ret;
return lttng_field_name_statedump(session, field, nesting);
static
int _lttng_sequence_field_statedump(struct lttng_session *session,
const struct lttng_kernel_event_field *field,
- size_t nesting)
+ size_t nesting,
+ const char *prev_field_name)
{
int ret;
const char *length_name;
WARN_ON_ONCE(!sequence_type);
length_name = sequence_type->length_name;
+ if (!length_name)
+ length_name = prev_field_name;
+ if (!length_name)
+ return -EINVAL;
if (sequence_type->alignment) {
ret = print_tabs(session, nesting);
ret = lttng_metadata_printf(session,
" _%s[ _%s ];\n",
field->name,
- sequence_type->length_name);
+ length_name);
return ret;
}
case lttng_kernel_type_variant:
ret = _lttng_variant_type_statedump(session,
lttng_kernel_get_type_variant(type),
- nesting);
+ nesting, NULL);
break;
/* Nested arrays and sequences are not supported yet. */
static
int _lttng_field_statedump(struct lttng_session *session,
const struct lttng_kernel_event_field *field,
- size_t nesting)
+ size_t nesting,
+ const char **prev_field_name_p)
{
+ const char *prev_field_name = NULL;
int ret = 0;
+ if (prev_field_name_p)
+ prev_field_name = *prev_field_name_p;
switch (field->type->type) {
case lttng_kernel_type_integer:
ret = _lttng_integer_field_statedump(session, field, nesting);
ret = _lttng_array_field_statedump(session, field, nesting);
break;
case lttng_kernel_type_sequence:
- ret = _lttng_sequence_field_statedump(session, field, nesting);
+ ret = _lttng_sequence_field_statedump(session, field, nesting, prev_field_name);
break;
case lttng_kernel_type_variant:
- ret = _lttng_variant_field_statedump(session, field, nesting);
+ ret = _lttng_variant_field_statedump(session, field, nesting, prev_field_name);
break;
default:
WARN_ON_ONCE(1);
return -EINVAL;
}
+ if (prev_field_name_p)
+ *prev_field_name_p = field->name;
return ret;
}
int _lttng_context_metadata_statedump(struct lttng_session *session,
struct lttng_kernel_ctx *ctx)
{
+ const char *prev_field_name = NULL;
int ret = 0;
int i;
for (i = 0; i < ctx->nr_fields; i++) {
const struct lttng_kernel_ctx_field *field = &ctx->fields[i];
- ret = _lttng_field_statedump(session, field->event_field, 2);
+ ret = _lttng_field_statedump(session, field->event_field, 2, &prev_field_name);
if (ret)
return ret;
}
int _lttng_fields_metadata_statedump(struct lttng_session *session,
struct lttng_kernel_event_recorder *event_recorder)
{
+ const char *prev_field_name = NULL;
const struct lttng_kernel_event_desc *desc = event_recorder->priv->parent.desc;
int ret = 0;
int i;
for (i = 0; i < desc->nr_fields; i++) {
const struct lttng_kernel_event_field *field = desc->fields[i];
- ret = _lttng_field_statedump(session, field, 2);
+ ret = _lttng_field_statedump(session, field, 2, &prev_field_name);
if (ret)
return ret;
}