X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fkernel-ctl%2Fkernel-ctl.c;h=a93d25102ad4bb7b2bf6a4afe8ad5d0edd3fb096;hp=1396cd9bbe846559ee345f6488fdd3808ac84ae1;hb=4dbc372b53ef1ac713497164e7a8b92100db7ae2;hpb=e316aad5fbbe3782872083cb68dfdd58bccea811 diff --git a/src/common/kernel-ctl/kernel-ctl.c b/src/common/kernel-ctl/kernel-ctl.c index 1396cd9bb..a93d25102 100644 --- a/src/common/kernel-ctl/kernel-ctl.c +++ b/src/common/kernel-ctl/kernel-ctl.c @@ -18,38 +18,175 @@ #define __USE_LINUX_IOCTL_DEFS #include +#include #include "kernel-ctl.h" #include "kernel-ioctl.h" +/* + * This flag indicates which version of the kernel ABI to use. The old + * ABI (namespace _old) does not support a 32-bit user-space when the + * kernel is 64-bit. The old ABI is kept here for compatibility but is + * deprecated and will be removed eventually. + */ +static int lttng_kernel_use_old_abi = -1; + +/* + * Execute the new or old ioctl depending on the ABI version. + * If the ABI version is not determined yet (lttng_kernel_use_old_abi = -1), + * this function tests if the new ABI is available and otherwise fallbacks + * on the old one. + * This function takes the fd on which the ioctl must be executed and the old + * and new request codes. + * It returns the return value of the ioctl executed. + */ +static inline int compat_ioctl_no_arg(int fd, unsigned long oldname, + unsigned long newname) +{ + int ret; + + if (lttng_kernel_use_old_abi == -1) { + ret = ioctl(fd, newname); + if (!ret) { + lttng_kernel_use_old_abi = 0; + goto end; + } + lttng_kernel_use_old_abi = 1; + } + if (lttng_kernel_use_old_abi) { + ret = ioctl(fd, oldname); + } else { + ret = ioctl(fd, newname); + } + +end: + return ret; +} + int kernctl_create_session(int fd) { - return ioctl(fd, LTTNG_KERNEL_SESSION); + return compat_ioctl_no_arg(fd, LTTNG_KERNEL_OLD_SESSION, + LTTNG_KERNEL_SESSION); } /* open the metadata global channel */ int kernctl_open_metadata(int fd, struct lttng_channel_attr *chops) { - return ioctl(fd, LTTNG_KERNEL_METADATA, chops); + struct lttng_kernel_old_channel old_channel; + struct lttng_kernel_channel channel; + + if (lttng_kernel_use_old_abi) { + old_channel.overwrite = chops->overwrite; + old_channel.subbuf_size = chops->subbuf_size; + old_channel.num_subbuf = chops->num_subbuf; + old_channel.switch_timer_interval = chops->switch_timer_interval; + old_channel.read_timer_interval = chops->read_timer_interval; + old_channel.output = chops->output; + memcpy(old_channel.padding, chops->padding, sizeof(old_channel.padding)); + + return ioctl(fd, LTTNG_KERNEL_OLD_METADATA, &old_channel); + } + + channel.overwrite = chops->overwrite; + channel.subbuf_size = chops->subbuf_size; + channel.num_subbuf = chops->num_subbuf; + channel.switch_timer_interval = chops->switch_timer_interval; + channel.read_timer_interval = chops->read_timer_interval; + channel.output = chops->output; + memcpy(channel.padding, chops->padding, sizeof(channel.padding)); + + return ioctl(fd, LTTNG_KERNEL_METADATA, &channel); } int kernctl_create_channel(int fd, struct lttng_channel_attr *chops) { - return ioctl(fd, LTTNG_KERNEL_CHANNEL, chops); + struct lttng_kernel_channel channel; + + if (lttng_kernel_use_old_abi) { + struct lttng_kernel_old_channel old_channel; + + old_channel.overwrite = chops->overwrite; + old_channel.subbuf_size = chops->subbuf_size; + old_channel.num_subbuf = chops->num_subbuf; + old_channel.switch_timer_interval = chops->switch_timer_interval; + old_channel.read_timer_interval = chops->read_timer_interval; + old_channel.output = chops->output; + memcpy(old_channel.padding, chops->padding, sizeof(old_channel.padding)); + + return ioctl(fd, LTTNG_KERNEL_OLD_CHANNEL, &old_channel); + } + + channel.overwrite = chops->overwrite; + channel.subbuf_size = chops->subbuf_size; + channel.num_subbuf = chops->num_subbuf; + channel.switch_timer_interval = chops->switch_timer_interval; + channel.read_timer_interval = chops->read_timer_interval; + channel.output = chops->output; + memcpy(channel.padding, chops->padding, sizeof(channel.padding)); + + return ioctl(fd, LTTNG_KERNEL_CHANNEL, &channel); } int kernctl_create_stream(int fd) { - return ioctl(fd, LTTNG_KERNEL_STREAM); + return compat_ioctl_no_arg(fd, LTTNG_KERNEL_OLD_STREAM, + LTTNG_KERNEL_STREAM); } int kernctl_create_event(int fd, struct lttng_kernel_event *ev) { + if (lttng_kernel_use_old_abi) { + struct lttng_kernel_old_event old_event; + + memcpy(old_event.name, ev->name, sizeof(old_event.name)); + old_event.instrumentation = ev->instrumentation; + switch (ev->instrumentation) { + case LTTNG_KERNEL_KPROBE: + old_event.u.kprobe.addr = ev->u.kprobe.addr; + old_event.u.kprobe.offset = ev->u.kprobe.offset; + memcpy(old_event.u.kprobe.symbol_name, + ev->u.kprobe.symbol_name, + sizeof(old_event.u.kprobe.symbol_name)); + break; + case LTTNG_KERNEL_KRETPROBE: + old_event.u.kretprobe.addr = ev->u.kretprobe.addr; + old_event.u.kretprobe.offset = ev->u.kretprobe.offset; + memcpy(old_event.u.kretprobe.symbol_name, + ev->u.kretprobe.symbol_name, + sizeof(old_event.u.kretprobe.symbol_name)); + break; + case LTTNG_KERNEL_FUNCTION: + memcpy(old_event.u.ftrace.symbol_name, + ev->u.ftrace.symbol_name, + sizeof(old_event.u.ftrace.symbol_name)); + break; + default: + break; + } + + return ioctl(fd, LTTNG_KERNEL_OLD_EVENT, &old_event); + } return ioctl(fd, LTTNG_KERNEL_EVENT, ev); } int kernctl_add_context(int fd, struct lttng_kernel_context *ctx) { + if (lttng_kernel_use_old_abi) { + struct lttng_kernel_old_context old_ctx; + + old_ctx.ctx = ctx->ctx; + /* only type that uses the union */ + if (ctx->ctx == LTTNG_KERNEL_CONTEXT_PERF_COUNTER) { + old_ctx.u.perf_counter.type = + ctx->u.perf_counter.type; + old_ctx.u.perf_counter.config = + ctx->u.perf_counter.config; + memcpy(old_ctx.u.perf_counter.name, + ctx->u.perf_counter.name, + sizeof(old_ctx.u.perf_counter.name)); + } + return ioctl(fd, LTTNG_KERNEL_OLD_CONTEXT, &old_ctx); + } return ioctl(fd, LTTNG_KERNEL_CONTEXT, ctx); } @@ -57,44 +194,98 @@ int kernctl_add_context(int fd, struct lttng_kernel_context *ctx) /* Enable event, channel and session ioctl */ int kernctl_enable(int fd) { - return ioctl(fd, LTTNG_KERNEL_ENABLE); + return compat_ioctl_no_arg(fd, LTTNG_KERNEL_OLD_ENABLE, + LTTNG_KERNEL_ENABLE); } /* Disable event, channel and session ioctl */ int kernctl_disable(int fd) { - return ioctl(fd, LTTNG_KERNEL_DISABLE); + return compat_ioctl_no_arg(fd, LTTNG_KERNEL_OLD_DISABLE, + LTTNG_KERNEL_DISABLE); } int kernctl_start_session(int fd) { - return ioctl(fd, LTTNG_KERNEL_SESSION_START); + return compat_ioctl_no_arg(fd, LTTNG_KERNEL_OLD_SESSION_START, + LTTNG_KERNEL_SESSION_START); } int kernctl_stop_session(int fd) { - return ioctl(fd, LTTNG_KERNEL_SESSION_STOP); + return compat_ioctl_no_arg(fd, LTTNG_KERNEL_OLD_SESSION_STOP, + LTTNG_KERNEL_SESSION_STOP); } - int kernctl_tracepoint_list(int fd) { - return ioctl(fd, LTTNG_KERNEL_TRACEPOINT_LIST); + return compat_ioctl_no_arg(fd, LTTNG_KERNEL_OLD_TRACEPOINT_LIST, + LTTNG_KERNEL_TRACEPOINT_LIST); } int kernctl_tracer_version(int fd, struct lttng_kernel_tracer_version *v) { - return ioctl(fd, LTTNG_KERNEL_TRACER_VERSION, v); + int ret; + + if (lttng_kernel_use_old_abi == -1) { + ret = ioctl(fd, LTTNG_KERNEL_TRACER_VERSION, v); + if (!ret) { + lttng_kernel_use_old_abi = 0; + goto end; + } + lttng_kernel_use_old_abi = 1; + } + if (lttng_kernel_use_old_abi) { + struct lttng_kernel_old_tracer_version old_v; + + ret = ioctl(fd, LTTNG_KERNEL_OLD_TRACER_VERSION, &old_v); + if (ret) { + goto end; + } + v->major = old_v.major; + v->minor = old_v.minor; + v->patchlevel = old_v.patchlevel; + } else { + ret = ioctl(fd, LTTNG_KERNEL_TRACER_VERSION, v); + } + +end: + return ret; } int kernctl_wait_quiescent(int fd) { - return ioctl(fd, LTTNG_KERNEL_WAIT_QUIESCENT); + return compat_ioctl_no_arg(fd, LTTNG_KERNEL_OLD_WAIT_QUIESCENT, + LTTNG_KERNEL_WAIT_QUIESCENT); } int kernctl_calibrate(int fd, struct lttng_kernel_calibrate *calibrate) { - return ioctl(fd, LTTNG_KERNEL_CALIBRATE, calibrate); + int ret; + + if (lttng_kernel_use_old_abi == -1) { + ret = ioctl(fd, LTTNG_KERNEL_CALIBRATE, calibrate); + if (!ret) { + lttng_kernel_use_old_abi = 0; + goto end; + } + lttng_kernel_use_old_abi = 1; + } + if (lttng_kernel_use_old_abi) { + struct lttng_kernel_old_calibrate old_calibrate; + + old_calibrate.type = calibrate->type; + ret = ioctl(fd, LTTNG_KERNEL_OLD_CALIBRATE, &old_calibrate); + if (ret) { + goto end; + } + calibrate->type = old_calibrate.type; + } else { + ret = ioctl(fd, LTTNG_KERNEL_CALIBRATE, calibrate); + } + +end: + return ret; } @@ -193,10 +384,3 @@ int kernctl_set_stream_id(int fd, unsigned long *stream_id) { return ioctl(fd, RING_BUFFER_SET_STREAM_ID, stream_id); } - -/* Get the offset of the stream_id in the packet header */ -int kernctl_get_net_stream_id_offset(int fd, unsigned long *offset) -{ - return ioctl(fd, LTTNG_KERNEL_STREAM_ID_OFFSET, offset); - -}