From: Francis Deslauriers Date: Thu, 28 Jun 2018 18:33:10 +0000 (-0400) Subject: run_as: add extract SDT probe offsets command X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=commitdiff_plain;h=0ef0325590ac65995f926a031e2f085531f74090 run_as: add extract SDT probe offsets command Signed-off-by: Francis Deslauriers Signed-off-by: Erica Bugden Signed-off-by: Jérémie Galarneau --- diff --git a/src/common/lttng-kernel.h b/src/common/lttng-kernel.h index 9d6d60c40..922da33c8 100644 --- a/src/common/lttng-kernel.h +++ b/src/common/lttng-kernel.h @@ -22,8 +22,11 @@ #include #include +#include +#include #define LTTNG_KERNEL_SYM_NAME_LEN 256 +#define LTTNG_KERNEL_MAX_UPROBE_NUM 32 /* * LTTng DebugFS ABI structures. diff --git a/src/common/runas-stub.c b/src/common/runas-stub.c index 99b44d32a..7af8b6e0c 100644 --- a/src/common/runas-stub.c +++ b/src/common/runas-stub.c @@ -45,6 +45,11 @@ int lttng_elf_get_symbol_offset(int fd, char *symbol, uint64_t *offset) { return -1; } +int lttng_elf_get_sdt_probe_offsets(int fd, const char *provider_name, + const char *probe_name, uint64_t **offsets, uint32_t *nb_probe) +{ + return -1; +} int run_as_create_worker(char *procname) { return -1; diff --git a/src/common/runas.c b/src/common/runas.c index bed25a463..3916d6754 100644 --- a/src/common/runas.c +++ b/src/common/runas.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -71,6 +72,11 @@ struct run_as_extract_elf_symbol_offset_data { char function[LTTNG_SYMBOL_NAME_LEN]; }; +struct run_as_extract_sdt_probe_offsets_data { + char probe_name[LTTNG_SYMBOL_NAME_LEN]; + char provider_name[LTTNG_SYMBOL_NAME_LEN]; +}; + struct run_as_mkdir_ret { int ret; }; @@ -91,6 +97,11 @@ struct run_as_extract_elf_symbol_offset_ret { uint64_t offset; }; +struct run_as_extract_sdt_probe_offsets_ret { + uint32_t num_offset; + uint64_t offsets[LTTNG_KERNEL_MAX_UPROBE_NUM]; +}; + enum run_as_cmd { RUN_AS_MKDIR, RUN_AS_OPEN, @@ -98,6 +109,7 @@ enum run_as_cmd { RUN_AS_RMDIR_RECURSIVE, RUN_AS_MKDIR_RECURSIVE, RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET, + RUN_AS_EXTRACT_SDT_PROBE_OFFSETS, }; struct run_as_data { @@ -109,6 +121,7 @@ struct run_as_data { struct run_as_unlink_data unlink; struct run_as_rmdir_recursive_data rmdir_recursive; struct run_as_extract_elf_symbol_offset_data extract_elf_symbol_offset; + struct run_as_extract_sdt_probe_offsets_data extract_sdt_probe_offsets; } u; uid_t uid; gid_t gid; @@ -137,6 +150,7 @@ struct run_as_ret { struct run_as_unlink_ret unlink; struct run_as_rmdir_recursive_ret rmdir_recursive; struct run_as_extract_elf_symbol_offset_ret extract_elf_symbol_offset; + struct run_as_extract_sdt_probe_offsets_ret extract_sdt_probe_offsets; } u; int _errno; bool _error; @@ -244,6 +258,46 @@ int _extract_elf_symbol_offset(struct run_as_data *data, return ret; } +static +int _extract_sdt_probe_offsets(struct run_as_data *data, + struct run_as_ret *ret_value) +{ + int ret = 0; + uint64_t *offsets = NULL; + uint32_t num_offset; + + ret_value->_error = false; + + /* On success, this call allocates the offsets paramater. */ + ret = lttng_elf_get_sdt_probe_offsets(data->fd, + data->u.extract_sdt_probe_offsets.provider_name, + data->u.extract_sdt_probe_offsets.probe_name, + &offsets, &num_offset); + + if (ret) { + DBG("Failed to extract SDT probe offsets"); + ret_value->_error = true; + goto end; + } + + if (num_offset <= 0 || num_offset > LTTNG_KERNEL_MAX_UPROBE_NUM) { + DBG("Wrong number of probes."); + ret = -1; + ret_value->_error = true; + goto free_offset; + } + + /* Copy the content of the offsets array to the ret struct. */ + memcpy(ret_value->u.extract_sdt_probe_offsets.offsets, + offsets, num_offset * sizeof(uint64_t)); + + ret_value->u.extract_sdt_probe_offsets.num_offset = num_offset; + +free_offset: + free(offsets); +end: + return ret; +} static run_as_fct run_as_enum_to_fct(enum run_as_cmd cmd) @@ -261,6 +315,8 @@ run_as_fct run_as_enum_to_fct(enum run_as_cmd cmd) return _mkdir_recursive; case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET: return _extract_elf_symbol_offset; + case RUN_AS_EXTRACT_SDT_PROBE_OFFSETS: + return _extract_sdt_probe_offsets; default: ERR("Unknown command %d", (int) cmd); return NULL; @@ -313,6 +369,7 @@ int send_fd_to_worker(struct run_as_worker *worker, enum run_as_cmd cmd, int fd) switch (cmd) { case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET: + case RUN_AS_EXTRACT_SDT_PROBE_OFFSETS: break; default: return 0; @@ -381,6 +438,7 @@ int recv_fd_from_master(struct run_as_worker *worker, enum run_as_cmd cmd, int * switch (cmd) { case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET: + case RUN_AS_EXTRACT_SDT_PROBE_OFFSETS: break; default: return 0; @@ -402,6 +460,7 @@ int cleanup_received_fd(enum run_as_cmd cmd, int fd) switch (cmd) { case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET: + case RUN_AS_EXTRACT_SDT_PROBE_OFFSETS: break; default: return 0; @@ -415,6 +474,7 @@ int cleanup_received_fd(enum run_as_cmd cmd, int fd) return ret; } + /* * Return < 0 on error, 0 if OK, 1 on hangup. */ @@ -875,6 +935,45 @@ int run_as_extract_elf_symbol_offset(int fd, const char* function, return 0; } +LTTNG_HIDDEN +int run_as_extract_sdt_probe_offsets(int fd, const char* provider_name, + const char* probe_name, uid_t uid, gid_t gid, + uint64_t **offsets, uint32_t *num_offset) +{ + struct run_as_data data; + struct run_as_ret ret; + + DBG3("extract_sdt_probe_offsets() on fd=%d, probe_name=%s and " + "provider_name=%s with for uid %d and gid %d", fd, probe_name, + provider_name, (int) uid, (int) gid); + + data.fd = fd; + + strncpy(data.u.extract_sdt_probe_offsets.probe_name, probe_name, LTTNG_SYMBOL_NAME_LEN - 1); + strncpy(data.u.extract_sdt_probe_offsets.provider_name, provider_name, LTTNG_SYMBOL_NAME_LEN - 1); + + data.u.extract_sdt_probe_offsets.probe_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; + data.u.extract_sdt_probe_offsets.provider_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; + + run_as(RUN_AS_EXTRACT_SDT_PROBE_OFFSETS, &data, &ret, uid, gid); + + errno = ret._errno; + + if (ret._error) { + return -1; + } + + *num_offset = ret.u.extract_sdt_probe_offsets.num_offset; + + *offsets = zmalloc(*num_offset * sizeof(uint64_t)); + if (!*offsets) { + return -ENOMEM; + } + + memcpy(*offsets, ret.u.extract_sdt_probe_offsets.offsets, *num_offset * sizeof(uint64_t)); + return 0; +} + static int reset_sighandler(void) { diff --git a/src/common/runas.h b/src/common/runas.h index 098d5c3aa..ba6482f69 100644 --- a/src/common/runas.h +++ b/src/common/runas.h @@ -19,9 +19,9 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include #include -#include LTTNG_HIDDEN int run_as_mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid); @@ -37,6 +37,10 @@ LTTNG_HIDDEN int run_as_extract_elf_symbol_offset(int fd, const char* function, uid_t uid, gid_t gid, uint64_t *offset); LTTNG_HIDDEN +int run_as_extract_sdt_probe_offsets(int fd, const char *provider_name, + const char* probe_name, uid_t uid, gid_t gid, + uint64_t **offsets, uint32_t *num_offset); +LTTNG_HIDDEN int run_as_create_worker(char *procname); LTTNG_HIDDEN void run_as_destroy_worker(void);