From: David Goulet Date: Thu, 26 Jun 2014 19:41:42 +0000 (-0400) Subject: Fix: auto load session in the auto/ directory X-Git-Tag: v2.5.0~29 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=13b5639ddc159b1a0396ae0bbca3674192107ed4;p=lttng-tools.git Fix: auto load session in the auto/ directory The session daemon will now automatically load sessions from the auto/ directory in the session config path. Both system config path and home config path are used. The session is only loaded if the UID of the session file matches the UID of the session daemon (or root). For that, a autoload parameter has been added to the config_load_session() function to indicate that we want to auto load sessions. Fixes #812 Signed-off-by: David Goulet --- diff --git a/src/bin/lttng-sessiond/load-session-thread.c b/src/bin/lttng-sessiond/load-session-thread.c index 845948e7c..38fa1f616 100644 --- a/src/bin/lttng-sessiond/load-session-thread.c +++ b/src/bin/lttng-sessiond/load-session-thread.c @@ -95,7 +95,8 @@ void *thread_load_session(void *data) goto end; } - ret = config_load_session(info->path, NULL, 0); + /* Override existing session and autoload also. */ + ret = config_load_session(info->path, NULL, 1, 1); if (ret) { ERR("Session load failed: %s", error_get_str(ret)); } diff --git a/src/bin/lttng/commands/load.c b/src/bin/lttng/commands/load.c index e732baa80..20d984389 100644 --- a/src/bin/lttng/commands/load.c +++ b/src/bin/lttng/commands/load.c @@ -102,7 +102,7 @@ int cmd_load(int argc, const char **argv) } } - ret = config_load_session(opt_input_path, session_name, opt_force); + ret = config_load_session(opt_input_path, session_name, opt_force, 0); if (ret) { ERR("%s", lttng_strerror(ret)); ret = -ret; diff --git a/src/common/config/config.c b/src/common/config/config.c index c9777d63f..b9c402108 100644 --- a/src/common/config/config.c +++ b/src/common/config/config.c @@ -2504,9 +2504,43 @@ end: return ret; } +/* + * Validate that the given path's credentials and the current process have the + * same UID. If so, return 0 else return 1 if it does NOT match. + */ +static int validate_path_creds(const char *path) +{ + int ret, uid = getuid(); + struct stat buf; + + assert(path); + + if (uid != 0) { + goto valid; + } + + ret = stat(path, &buf); + if (ret < 0) { + if (errno != ENOENT) { + PERROR("stat"); + } + ret = -LTTNG_ERR_INVALID; + goto valid; + } + + if (buf.st_uid != uid) { + goto invalid; + } + +valid: + return 0; +invalid: + return 1; +} + LTTNG_HIDDEN int config_load_session(const char *path, const char *session_name, - int override) + int override, unsigned int autoload) { int ret; struct session_config_validation_ctx validation_ctx = { 0 }; @@ -2517,34 +2551,56 @@ int config_load_session(const char *path, const char *session_name, } if (!path) { + char *home_path; + const char *sys_path; + + /* + * Try system session configuration path. Ignore error here so we can + * continue loading the home sessions. The above call should print an + * error to inform the user. + */ + if (autoload) { + sys_path = DEFAULT_SESSION_SYSTEM_CONFIGPATH "/" + DEFAULT_SESSION_CONFIG_AUTOLOAD; + } else { + sys_path = DEFAULT_SESSION_HOME_CONFIGPATH; + } + + ret = validate_path_creds(sys_path); + if (!ret && autoload) { + (void) load_session_from_path(sys_path, session_name, + &validation_ctx, override); + } + /* Try home path */ - char *home_path = utils_get_home_dir(); + home_path = utils_get_home_dir(); if (home_path) { - char *path; + char path[PATH_MAX]; - ret = asprintf(&path, DEFAULT_SESSION_HOME_CONFIGPATH, - home_path); + if (autoload) { + ret = snprintf(path, sizeof(path), + DEFAULT_SESSION_HOME_CONFIGPATH "/" + DEFAULT_SESSION_CONFIG_AUTOLOAD, home_path); + } else { + ret = snprintf(path, sizeof(path), + DEFAULT_SESSION_HOME_CONFIGPATH, home_path); + } if (ret < 0) { goto end; } + ret = validate_path_creds(path); + if (ret && autoload) { + ret = 0; + goto end; + } + ret = load_session_from_path(path, session_name, &validation_ctx, override); if (!ret || (ret && ret != -LTTNG_ERR_LOAD_SESSION_NOENT)) { /* Session found or an error occured */ - free(path); goto end; } - - free(path); - } - - /* Try system session configuration path */ - ret = load_session_from_path(DEFAULT_SESSION_SYSTEM_CONFIGPATH, - session_name, &validation_ctx, override); - if (!ret || (ret && ret != -LTTNG_ERR_LOAD_SESSION_NOENT)) { - /* Session found or an error occured */ - goto end; } } else { ret = access(path, F_OK); diff --git a/src/common/config/config.h b/src/common/config/config.h index a11eec9c7..9a5671ab0 100644 --- a/src/common/config/config.h +++ b/src/common/config/config.h @@ -199,12 +199,13 @@ int config_writer_write_element_string(struct config_writer *writer, * sessions from path if NULL. * * override Override current session configuration if it exists. + * autoload Tell to load the auto session(s). * * Returns zero if the session could be loaded successfully. Returns * a negative LTTNG_ERR code on error. */ LTTNG_HIDDEN int config_load_session(const char *path, const char *session_name, - int override); + int override, unsigned int autoload); #endif /* _CONFIG_H */ diff --git a/src/common/defaults.h b/src/common/defaults.h index b49bf4b33..8107d973b 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -123,6 +123,8 @@ /* Default session configuration file path */ #define DEFAULT_SESSION_PATH "sessions" +/* Auto load session in that directory. */ +#define DEFAULT_SESSION_CONFIG_AUTOLOAD "auto" #define DEFAULT_SESSION_HOME_CONFIGPATH DEFAULT_LTTNG_HOME_RUNDIR "/" \ DEFAULT_SESSION_PATH #define DEFAULT_SESSION_SYSTEM_CONFIGPATH DEFAULT_SYSTEM_CONFIGPATH "/" \ diff --git a/src/lib/lttng-ctl/load.c b/src/lib/lttng-ctl/load.c index 3811981ef..21619a683 100644 --- a/src/lib/lttng-ctl/load.c +++ b/src/lib/lttng-ctl/load.c @@ -166,7 +166,7 @@ int lttng_load_session(struct lttng_load_session_attr *attr) } ret = config_load_session(attr->input_url, attr->session_name, - attr->overwrite); + attr->overwrite, 0); end: return ret;