X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=src%2Fcommon%2Frunas.c;h=3916d6754314eadd4947b576dbcb4d98273ad861;hb=0ef0325590ac65995f926a031e2f085531f74090;hp=bed25a46368d61d875939acd1461e0b98a3af4cb;hpb=241e0a5ac6da55b41adaf516fbd36af332d94b3d;p=lttng-tools.git 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) {