From 4b526611b26f10b3a60302dba0853f71ee2bf38d Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 21 Apr 2022 16:28:45 -0400 Subject: [PATCH] Introduce backward compatibility protocol for error counters Introduce the "old" counter commands at the ust and ust-ctl sides of the communication protocol for compatibility with 2.13 lttng-ust. Signed-off-by: Mathieu Desnoyers Change-Id: I99f4a80f1e80561060cc6092c260e60128d49f3f --- include/Makefile.am | 1 + include/lttng/ust-abi-old.h | 68 +++++++++++++ include/lttng/ust-abi.h | 10 +- src/common/ustcomm.h | 4 + src/lib/lttng-ust-ctl/ustctl.c | 174 ++++++++++++++++++++++++++++++++- 5 files changed, 250 insertions(+), 7 deletions(-) create mode 100644 include/lttng/ust-abi-old.h diff --git a/include/Makefile.am b/include/Makefile.am index 368fa261..faa00cd9 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -21,6 +21,7 @@ nobase_include_HEADERS = \ lttng/ust-common.h \ lttng/ust-ctl.h \ lttng/ust-abi.h \ + lttng/ust-abi-old.h \ lttng/ust-tracer.h \ lttng/ust-compiler.h \ lttng/ust-fork.h \ diff --git a/include/lttng/ust-abi-old.h b/include/lttng/ust-abi-old.h new file mode 100644 index 00000000..543c4273 --- /dev/null +++ b/include/lttng/ust-abi-old.h @@ -0,0 +1,68 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * + * LTTng-UST ABI header + */ + +#ifndef _LTTNG_UST_ABI_OLD_H +#define _LTTNG_UST_ABI_OLD_H + +#include +#include + +#define LTTNG_UST_ABI_OLD_SYM_NAME_LEN 256 +#define LTTNG_UST_ABI_OLD_COUNTER_DIMENSION_MAX 4 + +struct lttng_ust_abi_old_counter_dimension { + uint64_t size; + uint64_t underflow_index; + uint64_t overflow_index; + uint8_t has_underflow; + uint8_t has_overflow; +} __attribute__((packed)); + +#define LTTNG_UST_ABI_OLD_COUNTER_CONF_PADDING1 67 +struct lttng_ust_abi_old_counter_conf { + uint32_t arithmetic; /* enum lttng_ust_abi_counter_arithmetic */ + uint32_t bitness; /* enum lttng_ust_abi_counter_bitness */ + uint32_t number_dimensions; + int64_t global_sum_step; + struct lttng_ust_abi_old_counter_dimension dimensions[LTTNG_UST_ABI_OLD_COUNTER_DIMENSION_MAX]; + uint8_t coalesce_hits; + char padding[LTTNG_UST_ABI_OLD_COUNTER_CONF_PADDING1]; +} __attribute__((packed)); + +#define LTTNG_UST_ABI_OLD_COUNTER_PADDING1 (LTTNG_UST_ABI_OLD_SYM_NAME_LEN + 32) +#define LTTNG_UST_ABI_OLD_COUNTER_DATA_MAX_LEN 4096U +struct lttng_ust_abi_old_counter { + uint64_t len; + char padding[LTTNG_UST_ABI_OLD_COUNTER_PADDING1]; + char data[]; /* variable sized data */ +} __attribute__((packed)); + +#define LTTNG_UST_ABI_OLD_COUNTER_GLOBAL_PADDING1 (LTTNG_UST_ABI_OLD_SYM_NAME_LEN + 32) +struct lttng_ust_abi_old_counter_global { + uint64_t len; /* shm len */ + char padding[LTTNG_UST_ABI_OLD_COUNTER_GLOBAL_PADDING1]; +} __attribute__((packed)); + +#define LTTNG_UST_ABI_OLD_COUNTER_CPU_PADDING1 (LTTNG_UST_ABI_OLD_SYM_NAME_LEN + 32) +struct lttng_ust_abi_old_counter_cpu { + uint64_t len; /* shm len */ + uint32_t cpu_nr; + char padding[LTTNG_UST_ABI_OLD_COUNTER_CPU_PADDING1]; +} __attribute__((packed)); + +/* Event notifier group commands */ +#define LTTNG_UST_ABI_OLD_COUNTER \ + LTTNG_UST_ABI_CMDW(0xC0, struct lttng_ust_abi_old_counter) + +/* Counter commands */ +#define LTTNG_UST_ABI_OLD_COUNTER_GLOBAL \ + LTTNG_UST_ABI_CMDW(0xD0, struct lttng_ust_abi_old_counter_global) +#define LTTNG_UST_ABI_OLD_COUNTER_CPU \ + LTTNG_UST_ABI_CMDW(0xD1, struct lttng_ust_abi_old_counter_cpu) + +#endif /* _LTTNG_UST_ABI_OLD_H */ diff --git a/include/lttng/ust-abi.h b/include/lttng/ust-abi.h index 9816862f..7db52c4e 100644 --- a/include/lttng/ust-abi.h +++ b/include/lttng/ust-abi.h @@ -430,16 +430,18 @@ struct lttng_ust_abi_event_exclusion { #define LTTNG_UST_ABI_CAPTURE LTTNG_UST_ABI_CMD(0xB6) /* Session and event notifier group commands */ +/* (0xC0) reserved for old ABI. */ #define LTTNG_UST_ABI_COUNTER \ - LTTNG_UST_ABI_CMDV(0xC0, struct lttng_ust_abi_counter_conf) + LTTNG_UST_ABI_CMDV(0xC1, struct lttng_ust_abi_counter_conf) /* Counter commands */ +/* (0xD0, 0xD1) reserved for old ABI. */ #define LTTNG_UST_ABI_COUNTER_GLOBAL \ - LTTNG_UST_ABI_CMDV(0xD0, struct lttng_ust_abi_counter_global) + LTTNG_UST_ABI_CMDV(0xD2, struct lttng_ust_abi_counter_global) #define LTTNG_UST_ABI_COUNTER_CPU \ - LTTNG_UST_ABI_CMDV(0xD1, struct lttng_ust_abi_counter_cpu) + LTTNG_UST_ABI_CMDV(0xD3, struct lttng_ust_abi_counter_cpu) #define LTTNG_UST_ABI_COUNTER_EVENT \ - LTTNG_UST_ABI_CMDV(0xD2, struct lttng_ust_abi_counter_event) + LTTNG_UST_ABI_CMDV(0xD4, struct lttng_ust_abi_counter_event) #define LTTNG_UST_ABI_ROOT_HANDLE 0 diff --git a/src/common/ustcomm.h b/src/common/ustcomm.h index bbd33868..ce8a6ce7 100644 --- a/src/common/ustcomm.h +++ b/src/common/ustcomm.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -90,6 +91,9 @@ struct ustcomm_ust_msg { uint32_t reloc_offset; uint64_t seqnum; } __attribute__((packed)) capture; + struct lttng_ust_abi_old_counter counter_old; + struct lttng_ust_abi_old_counter_global counter_global_old; + struct lttng_ust_abi_old_counter_cpu counter_cpu_old; struct { uint32_t cmd_len; } __attribute__((packed)) var_len_cmd; diff --git a/src/lib/lttng-ust-ctl/ustctl.c b/src/lib/lttng-ust-ctl/ustctl.c index 285c295b..ba4edbb4 100644 --- a/src/lib/lttng-ust-ctl/ustctl.c +++ b/src/lib/lttng-ust-ctl/ustctl.c @@ -3143,6 +3143,162 @@ void lttng_ust_ctl_destroy_counter(struct lttng_ust_ctl_daemon_counter *counter) free(counter); } +/* + * Protocol for LTTNG_UST_ABI_OLD_COUNTER command: + * + * - send: struct ustcomm_ust_msg + * - receive: struct ustcomm_ust_reply + * - send: counter data + * - receive: struct ustcomm_ust_reply (actual command return code) + */ +static +int lttng_ust_ctl_send_old_counter_data_to_ust(int sock, int parent_handle, + struct lttng_ust_abi_object_data *counter_data) +{ + const struct lttng_ust_abi_counter_conf *counter_conf = counter_data->u.counter.data; + const struct lttng_ust_abi_counter_dimension *dimension; + struct lttng_ust_abi_old_counter_conf old_counter_conf = {}; + struct ustcomm_ust_msg lum = {}; + struct ustcomm_ust_reply lur; + int ret; + size_t size; + ssize_t len; + + if (!counter_data) + return -EINVAL; + + if (counter_conf->number_dimensions != 1) + return -EINVAL; + old_counter_conf.coalesce_hits = (counter_conf->flags & LTTNG_UST_ABI_COUNTER_CONF_FLAG_COALESCE_HITS) ? 1 : 0; + old_counter_conf.arithmetic = counter_conf->arithmetic; + old_counter_conf.bitness = counter_conf->bitness; + old_counter_conf.global_sum_step = counter_conf->global_sum_step; + + dimension = (struct lttng_ust_abi_counter_dimension *)((char *)counter_conf + sizeof(struct lttng_ust_abi_counter_conf)); + old_counter_conf.number_dimensions = 1; + old_counter_conf.dimensions[0].size = dimension->size; + old_counter_conf.dimensions[0].has_underflow = (dimension->flags & LTTNG_UST_ABI_COUNTER_DIMENSION_FLAG_UNDERFLOW) ? 1 : 0; + old_counter_conf.dimensions[0].has_overflow = (dimension->flags & LTTNG_UST_ABI_COUNTER_DIMENSION_FLAG_OVERFLOW) ? 1 : 0; + old_counter_conf.dimensions[0].underflow_index = dimension->underflow_index; + old_counter_conf.dimensions[0].overflow_index = dimension->overflow_index; + + size = sizeof(old_counter_conf); + lum.handle = parent_handle; + lum.cmd = LTTNG_UST_ABI_OLD_COUNTER; + lum.u.counter_old.len = size; + ret = ustcomm_send_app_cmd(sock, &lum, &lur); + if (ret) + return ret; + + /* Send counter data */ + len = ustcomm_send_unix_sock(sock, &old_counter_conf, size); + if (len != size) { + if (len < 0) + return len; + else + return -EIO; + } + + ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); + if (!ret) { + counter_data->handle = lur.ret_val; + } + return ret; +} + +/* + * Protocol for LTTNG_UST_ABI_OLD_COUNTER_GLOBAL command: + * + * - send: struct ustcomm_ust_msg + * - receive: struct ustcomm_ust_reply + * - send: file descriptor + * - receive: struct ustcomm_ust_reply (actual command return code) + */ +static +int lttng_ust_ctl_send_old_counter_global_data_to_ust(int sock, + struct lttng_ust_abi_object_data *counter_data, + struct lttng_ust_abi_object_data *counter_global_data) +{ + struct ustcomm_ust_msg lum = {}; + struct ustcomm_ust_reply lur; + int ret, shm_fd[1]; + size_t size; + ssize_t len; + + if (!counter_data || !counter_global_data) + return -EINVAL; + + size = counter_global_data->size; + lum.handle = counter_data->handle; /* parent handle */ + lum.cmd = LTTNG_UST_ABI_OLD_COUNTER_GLOBAL; + lum.u.counter_global_old.len = size; + ret = ustcomm_send_app_cmd(sock, &lum, &lur); + if (ret) + return ret; + + shm_fd[0] = counter_global_data->u.counter_global.shm_fd; + len = ustcomm_send_fds_unix_sock(sock, shm_fd, 1); + if (len <= 0) { + if (len < 0) + return len; + else + return -EIO; + } + + ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); + if (!ret) { + counter_global_data->handle = lur.ret_val; + } + return ret; +} + +/* + * Protocol for LTTNG_UST_ABI_OLD_COUNTER_CPU command: + * + * - send: struct ustcomm_ust_msg + * - receive: struct ustcomm_ust_reply + * - send: file descriptor + * - receive: struct ustcomm_ust_reply (actual command return code) + */ +static +int lttng_ust_ctl_send_old_counter_cpu_data_to_ust(int sock, + struct lttng_ust_abi_object_data *counter_data, + struct lttng_ust_abi_object_data *counter_cpu_data) +{ + struct ustcomm_ust_msg lum = {}; + struct ustcomm_ust_reply lur; + int ret, shm_fd[1]; + size_t size; + ssize_t len; + + if (!counter_data || !counter_cpu_data) + return -EINVAL; + + size = counter_cpu_data->size; + lum.handle = counter_data->handle; /* parent handle */ + lum.cmd = LTTNG_UST_ABI_OLD_COUNTER_CPU; + lum.u.counter_cpu_old.len = size; + lum.u.counter_cpu_old.cpu_nr = counter_cpu_data->u.counter_cpu.cpu_nr; + ret = ustcomm_send_app_cmd(sock, &lum, &lur); + if (ret) + return ret; + + shm_fd[0] = counter_cpu_data->u.counter_global.shm_fd; + len = ustcomm_send_fds_unix_sock(sock, shm_fd, 1); + if (len <= 0) { + if (len < 0) + return len; + else + return -EIO; + } + + ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd); + if (!ret) { + counter_cpu_data->handle = lur.ret_val; + } + return ret; +} + /* * Protocol for LTTNG_UST_ABI_COUNTER command: * @@ -3168,8 +3324,12 @@ int lttng_ust_ctl_send_counter_data_to_ust(int sock, int parent_handle, lum.cmd = LTTNG_UST_ABI_COUNTER; lum.u.var_len_cmd.cmd_len = size; ret = ustcomm_send_app_cmd(sock, &lum, &lur); - if (ret) + if (ret == -LTTNG_UST_ERR_INVAL) { + return lttng_ust_ctl_send_old_counter_data_to_ust(sock, parent_handle, counter_data); + } + if (ret) { return ret; + } /* Send var len cmd */ len = ustcomm_send_unix_sock(sock, counter_data->u.counter.data, size); @@ -3214,8 +3374,12 @@ int lttng_ust_ctl_send_counter_global_data_to_ust(int sock, lum.cmd = LTTNG_UST_ABI_COUNTER_GLOBAL; lum.u.var_len_cmd.cmd_len = sizeof(struct lttng_ust_abi_counter_global); ret = ustcomm_send_app_cmd(sock, &lum, &lur); - if (ret) + if (ret == -LTTNG_UST_ERR_INVAL) { + return lttng_ust_ctl_send_old_counter_global_data_to_ust(sock, counter_data, counter_global_data); + } + if (ret) { return ret; + } counter_global.len = sizeof(struct lttng_ust_abi_counter_global); counter_global.shm_len = size; @@ -3272,8 +3436,12 @@ int lttng_ust_ctl_send_counter_cpu_data_to_ust(int sock, lum.cmd = LTTNG_UST_ABI_COUNTER_CPU; lum.u.var_len_cmd.cmd_len = sizeof(struct lttng_ust_abi_counter_cpu); ret = ustcomm_send_app_cmd(sock, &lum, &lur); - if (ret) + if (ret == -LTTNG_UST_ERR_INVAL) { + return lttng_ust_ctl_send_old_counter_cpu_data_to_ust(sock, counter_data, counter_cpu_data); + } + if (ret) { return ret; + } counter_cpu.len = sizeof(struct lttng_ust_abi_counter_cpu); counter_cpu.shm_len = size; -- 2.34.1