From: Jonathan Rajotte Date: Wed, 16 May 2018 22:24:01 +0000 (-0400) Subject: relayd: introduce --working-directory/-w options X-Git-Tag: v2.12.0-rc1~295 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=ce9ee1fb2847b1603c4382c82aef95121f0e3d07 relayd: introduce --working-directory/-w options This new option allows the user to specify the working directory (CWD) of the lttng-relayd process. This is especially useful when lttng-relayd is started in daemon mode (-d) because by default the CWD is set to "/". This can help control where coredumps, if any, get generated. Signed-off-by: Jonathan Rajotte Signed-off-by: Jérémie Galarneau --- diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 2836c489c..ad97a0b9b 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -96,7 +96,7 @@ enum relay_connection_status { }; /* command line options */ -char *opt_output_path; +char *opt_output_path, *opt_working_directory; static int opt_daemon, opt_background, opt_print_version; /* @@ -184,6 +184,7 @@ static struct option long_options[] = { { "verbose", 0, 0, 'v', }, { "config", 1, 0, 'f' }, { "version", 0, 0, 'V' }, + { "working-directory", 1, 0, 'w', }, { NULL, 0, 0, 0, }, }; @@ -311,6 +312,20 @@ static int set_option(int opt, const char *arg, const char *optname) } } break; + case 'w': + if (lttng_is_setuid_setgid()) { + WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.", + "-w, --working-directory"); + } else { + ret = asprintf(&opt_working_directory, "%s", arg); + if (ret < 0) { + ret = -errno; + PERROR("asprintf opt_working_directory"); + goto end; + } + } + break; + case 'v': /* Verbose level can increase using multiple -v */ if (arg) { @@ -541,8 +556,8 @@ static void relayd_cleanup(void) if (sessions_ht) lttng_ht_destroy(sessions_ht); - /* free the dynamically allocated opt_output_path */ free(opt_output_path); + free(opt_working_directory); /* Close thread quit pipes */ utils_close_pipe(thread_quit_pipe); @@ -3729,6 +3744,14 @@ int main(int argc, char **argv) } } + if (opt_working_directory) { + ret = utils_change_working_directory(opt_working_directory); + if (ret) { + /* All errors are already logged. */ + goto exit_options; + } + } + sessiond_trace_chunk_registry = sessiond_trace_chunk_registry_create(); if (!sessiond_trace_chunk_registry) { ERR("Failed to initialize session daemon trace chunk registry"); diff --git a/src/common/utils.c b/src/common/utils.c index 3cdb6b760..0147c8c99 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -1501,3 +1501,35 @@ int utils_get_memory_total(size_t *value) { return read_proc_meminfo_field(PROC_MEMINFO_MEMTOTAL_LINE, value); } + +LTTNG_HIDDEN +int utils_change_working_directory(const char *path) +{ + int ret; + + assert(path); + + DBG("Changing working directory to \"%s\"", path); + ret = chdir(path); + if (ret) { + PERROR("Failed to change working directory to \"%s\"", path); + goto end; + } + + /* Check for write access */ + if (access(path, W_OK)) { + if (errno == EACCES) { + /* + * Do not treat this as an error since the permission + * might change in the lifetime of the process + */ + DBG("Working directory \"%s\" is not writable", path); + } else { + PERROR("Failed to check if working directory \"%s\" is writable", + path); + } + } + +end: + return ret; +} diff --git a/src/common/utils.h b/src/common/utils.h index 11388c903..27a6f4849 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -63,5 +63,6 @@ int utils_truncate_stream_file(int fd, off_t length); int utils_show_help(int section, const char *page_name, const char *help_msg); int utils_get_memory_available(size_t *value); int utils_get_memory_total(size_t *value); +int utils_change_working_directory(const char *path); #endif /* _COMMON_UTILS_H */