From: Jonathan Rajotte Date: Wed, 13 May 2020 23:02:43 +0000 (-0400) Subject: Support capture for kernel tracer X-Git-Tag: v2.13.0-rc1~228 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=bbd6675c857ad9bf95e59446476cab19d1f6736e Support capture for kernel tracer Signed-off-by: Jonathan Rajotte Signed-off-by: Jérémie Galarneau Change-Id: I26167d259daa8e356a1bb03831ccf6e570b8e305 Depends-on: lttng-ust: I8423c510bf6af2f9bf85256e8d6f931d36f7054b --- diff --git a/src/bin/lttng-sessiond/kernel.c b/src/bin/lttng-sessiond/kernel.c index 23e8eac2a..54e745474 100644 --- a/src/bin/lttng-sessiond/kernel.c +++ b/src/bin/lttng-sessiond/kernel.c @@ -2299,8 +2299,10 @@ static enum lttng_error_code kernel_create_event_notifier_rule( enum lttng_event_rule_type event_rule_type; struct ltt_kernel_event_notifier_rule *event_notifier_rule; struct lttng_kernel_event_notifier kernel_event_notifier = {}; + unsigned int capture_bytecode_count = 0, i; const struct lttng_condition *condition = NULL; const struct lttng_event_rule *event_rule = NULL; + enum lttng_condition_status cond_status; assert(trigger); @@ -2393,6 +2395,31 @@ static enum lttng_error_code kernel_create_event_notifier_rule( } } + /* Set the capture bytecode, if any. */ + cond_status = lttng_condition_event_rule_get_capture_descriptor_count( + condition, &capture_bytecode_count); + assert(cond_status == LTTNG_CONDITION_STATUS_OK); + + for (i = 0; i < capture_bytecode_count; i++) { + const struct lttng_bytecode *capture_bytecode = + lttng_condition_event_rule_get_capture_bytecode_at_index( + condition, i); + + if (capture_bytecode == NULL) { + ERR("Unexpected NULL capture bytecode on condition"); + error_code_ret = LTTNG_ERR_KERN_ENABLE_FAIL; + goto error; + } + + ret = kernctl_capture(event_notifier_rule->fd, capture_bytecode); + if (ret < 0) { + ERR("Failed to set capture bytecode on event notifier rule fd: fd = %d", + event_notifier_rule->fd); + error_code_ret = LTTNG_ERR_KERN_ENABLE_FAIL; + goto error; + } + } + err = kernctl_enable(event_notifier_rule->fd); if (err < 0) { switch (-err) { diff --git a/src/bin/lttng-sessiond/notification-thread-events.c b/src/bin/lttng-sessiond/notification-thread-events.c index ccd285a81..413f1848b 100644 --- a/src/bin/lttng-sessiond/notification-thread-events.c +++ b/src/bin/lttng-sessiond/notification-thread-events.c @@ -4291,7 +4291,7 @@ struct lttng_event_notifier_notification *recv_one_event_notifier_notification( break; case LTTNG_DOMAIN_KERNEL: token = kernel_notification.token; - capture_buffer_size = 0; + capture_buffer_size = kernel_notification.capture_buf_size; break; default: abort(); diff --git a/src/common/kernel-ctl/kernel-ctl.c b/src/common/kernel-ctl/kernel-ctl.c index bb6602e2b..94e22ff06 100644 --- a/src/common/kernel-ctl/kernel-ctl.c +++ b/src/common/kernel-ctl/kernel-ctl.c @@ -437,6 +437,28 @@ int kernctl_create_event_notifier(int group_fd, LTTNG_KERNEL_EVENT_NOTIFIER_CREATE, event_notifier); } +int kernctl_capture(int fd, const struct lttng_bytecode *capture) +{ + int ret; + struct lttng_kernel_capture_bytecode *kb; + + /* Translate bytecode to kernel bytecode. */ + kb = zmalloc(sizeof(*kb) + capture->len); + if (!kb) { + ret = -ENOMEM; + goto end; + } + + kb->len = capture->len; + kb->reloc_offset = capture->reloc_table_offset; + kb->seqnum = capture->seqnum; + memcpy(kb->data, capture->data, capture->len); + ret = LTTNG_IOCTL_CHECK(fd, LTTNG_KERNEL_CAPTURE, kb); + free(kb); +end: + return ret; +} + int kernctl_filter(int fd, const struct lttng_bytecode *filter) { struct lttng_kernel_filter_bytecode *kb; diff --git a/src/common/kernel-ctl/kernel-ctl.h b/src/common/kernel-ctl/kernel-ctl.h index 3bbe69f48..25cb3b52b 100644 --- a/src/common/kernel-ctl/kernel-ctl.h +++ b/src/common/kernel-ctl/kernel-ctl.h @@ -38,6 +38,7 @@ int kernctl_create_event_notifier(int fd, /* Apply on event file descriptor. */ int kernctl_filter(int fd, const struct lttng_bytecode *filter); int kernctl_add_callsite(int fd, struct lttng_kernel_event_callsite *callsite); +int kernctl_capture(int fd, const struct lttng_bytecode *capture); int kernctl_tracepoint_list(int fd); int kernctl_syscall_list(int fd); diff --git a/src/common/kernel-ctl/kernel-ioctl.h b/src/common/kernel-ctl/kernel-ioctl.h index 8fa0a7d10..f68d5d156 100644 --- a/src/common/kernel-ctl/kernel-ioctl.h +++ b/src/common/kernel-ctl/kernel-ioctl.h @@ -178,4 +178,7 @@ #define LTTNG_KERNEL_EVENT_NOTIFIER_GROUP_NOTIFICATION_FD \ _IO(0xF6, 0xB1) +/* Trigger file descriptor ioctl */ +#define LTTNG_KERNEL_CAPTURE _IO(0xF6, 0xB8) + #endif /* _LTT_KERNEL_IOCTL_H */ diff --git a/src/common/lttng-kernel.h b/src/common/lttng-kernel.h index cd343bb76..e8647f439 100644 --- a/src/common/lttng-kernel.h +++ b/src/common/lttng-kernel.h @@ -184,12 +184,21 @@ struct lttng_kernel_event_notifier { char padding[LTTNG_KERNEL_EVENT_NOTIFIER_PADDING]; } LTTNG_PACKED; -#define LTTNG_KERNEL_EVENT_NOTIFIER_NOTIFICATION_PADDING 34 +#define LTTNG_KERNEL_EVENT_NOTIFIER_NOTIFICATION_PADDING 32 struct lttng_kernel_event_notifier_notification { uint64_t token; + uint16_t capture_buf_size; char padding[LTTNG_KERNEL_EVENT_NOTIFIER_NOTIFICATION_PADDING]; } LTTNG_PACKED; +#define LTTNG_KERNEL_CAPTURE_BYTECODE_MAX_LEN 65536 +struct lttng_kernel_capture_bytecode { + uint32_t len; + uint32_t reloc_offset; + uint64_t seqnum; + char data[0]; +} LTTNG_PACKED; + struct lttng_kernel_tracer_version { uint32_t major; uint32_t minor;