diff --git a/src/lxc/log.c b/src/lxc/log.c index 3c6e4d188..61280bc0b 100644 --- a/src/lxc/log.c +++ b/src/lxc/log.c @@ -35,15 +35,19 @@ #include "log.h" #include "caps.h" +#include "utils.h" #define LXC_LOG_PREFIX_SIZE 32 #define LXC_LOG_BUFFER_SIZE 512 int lxc_log_fd = -1; static char log_prefix[LXC_LOG_PREFIX_SIZE] = "lxc"; +static char *log_fname = NULL; +/* command line values for logfile or logpriority should always override + * values from the configuration file or defaults + */ +static int lxc_logfile_specified = 0; static int lxc_loglevel_specified = 0; -// if logfile was specifed on command line, it won't be overridden by lxc.logfile -static int lxc_log_specified = 0; lxc_log_define(lxc_log, lxc); @@ -119,12 +123,6 @@ struct lxc_log_category lxc_log_category_lxc = { }; /*---------------------------------------------------------------------------*/ -extern void lxc_log_setprefix(const char *prefix) -{ - strncpy(log_prefix, prefix, sizeof(log_prefix)); - log_prefix[sizeof(log_prefix) - 1] = 0; -} - static int build_dir(const char *name) { char *n = strdup(name); // because we'll be modifying it @@ -180,28 +178,39 @@ static int log_open(const char *name) return newfd; } -static char *build_log_path(const char *name) +/* + * Build the path to the log file + * @name : the name of the container + * @lxcpath : the lxcpath to use as a basename or NULL to use LOGPATH + * Returns malloced path on sucess, or NULL on failure + */ +static char *build_log_path(const char *name, const char *lxcpath) { char *p; int len, ret; /* - * '$logpath' + '/' + '$name' + '.log' + '\0' - * or + * If USE_CONFIGPATH_LOGS is true the resulting path will be: * '$logpath' + '/' + '$name' + '/' + '$name' + '.log' + '\0' - * sizeof(LOGPATH) includes its \0 + * + * If USE_CONFIGPATH_LOGS is false the resulting path will be: + * '$logpath' + '/' + '$name' + '.log' + '\0' */ - len = sizeof(LOGPATH) + strlen(name) + 6; + len = strlen(name) + 6; /* 6 == '/' + '.log' + '\0' */ + if (!lxcpath) + lxcpath = LOGPATH; #if USE_CONFIGPATH_LOGS - len += strlen(name) + 1; /* add "/$container_name/" */ + len += strlen(lxcpath) + 1 + strlen(name) + 1; /* add "/$container_name/" */ +#else + len += strlen(lxcpath) + 1; #endif p = malloc(len); if (!p) return p; #if USE_CONFIGPATH_LOGS - ret = snprintf(p, len, "%s/%s/%s.log", LOGPATH, name, name); + ret = snprintf(p, len, "%s/%s/%s.log", lxcpath, name, name); #else - ret = snprintf(p, len, "%s/%s.log", LOGPATH, name); + ret = snprintf(p, len, "%s/%s.log", lxcpath, name); #endif if (ret < 0 || ret >= len) { free(p); @@ -210,19 +219,67 @@ static char *build_log_path(const char *name) return p; } -int do_lxc_log_set_file(const char *fname, int from_default); +/* + * This can be called: + * 1. when a program calls lxc_log_init with no logfile parameter (in which + * case the default is used). In this case lxc.logfile can override this. + * 2. when a program calls lxc_log_init with a logfile parameter. In this + * case we don't want lxc.logfile to override this. + * 3. When a lxc.logfile entry is found in config file. + */ +static int __lxc_log_set_file(const char *fname, int create_dirs) +{ + if (lxc_log_fd != -1) { + // we are overriding the default. + close(lxc_log_fd); + free(log_fname); + } + +#if USE_CONFIGPATH_LOGS + // we don't build_dir for the default if the default is + // i.e. /var/lib/lxc/$container/$container.log + if (create_dirs) +#endif + if (build_dir(fname)) { + ERROR("failed to create dir for log file \"%s\" : %s", fname, + strerror(errno)); + return -1; + } + + lxc_log_fd = log_open(fname); + if (lxc_log_fd == -1) + return -1; + + log_fname = strdup(fname); + return 0; +} + +static int _lxc_log_set_file(const char *name, const char *lxcpath, int create_dirs) +{ + char *logfile; + int ret; + + logfile = build_log_path(name, lxcpath); + if (!logfile) { + ERROR("could not build log path"); + return -1; + } + ret = __lxc_log_set_file(logfile, create_dirs); + free(logfile); + return ret; +} -/*---------------------------------------------------------------------------*/ extern int lxc_log_init(const char *name, const char *file, - const char *priority, const char *prefix, int quiet) + const char *priority, const char *prefix, int quiet, + const char *lxcpath) { int lxc_priority = LXC_LOG_PRIORITY_ERROR; int ret; - char *tmpfile = NULL; - int want_lxc_log_specified = 0; - if (lxc_log_fd != -1) + if (lxc_log_fd != -1) { + WARN("lxc_log_init called with log already initialized"); return 0; + } if (priority) { lxc_loglevel_specified = 1; @@ -241,38 +298,38 @@ extern int lxc_log_init(const char *name, const char *file, lxc_log_category_lxc.appender->next = &log_appender_stderr; if (prefix) - lxc_log_setprefix(prefix); + lxc_log_set_prefix(prefix); - if (file && strcmp(file, "none") == 0) { - return 0; - } - - if (!file) { - tmpfile = build_log_path(name); - if (!tmpfile) { - ERROR("could not build log path"); - return -1; - } + if (file) { + lxc_logfile_specified = 1; + if (strcmp(file, "none") == 0) + return 0; + ret = __lxc_log_set_file(file, 1); } else { - want_lxc_log_specified = 1; + ret = -1; + + /* try LOGPATH if lxcpath is the default */ + if (strcmp(lxcpath, default_lxc_path()) == 0) + ret = _lxc_log_set_file(name, NULL, 0); + + /* try in lxcpath */ + if (ret < 0) + ret = _lxc_log_set_file(name, lxcpath, 1); + + /* try LOGPATH in case its writable by the caller */ + if (ret < 0) + ret = _lxc_log_set_file(name, NULL, 0); } - ret = do_lxc_log_set_file(tmpfile ? tmpfile : file, !want_lxc_log_specified); - - if (want_lxc_log_specified) - lxc_log_specified = 1; /* - * If !want_lxc_log_specified, that is, if the user did not request - * this logpath, then ignore failures and continue logging to console + * If !file, that is, if the user did not request this logpath, then + * ignore failures and continue logging to console */ - if (!want_lxc_log_specified && ret != 0) { + if (!file && ret != 0) { INFO("Ignoring failure to open default logfile."); ret = 0; } - if (tmpfile) - free(tmpfile); - return ret; } @@ -293,51 +350,6 @@ extern int lxc_log_set_level(int level) return 0; } -char *log_fname; // default to NULL, set in lxc_log_set_file. -/* - * This can be called: - * 1. when a program calls lxc_log_init with no logfile parameter (in which - * case the default is used). In this case lxc.logfile can override this. - * 2. when a program calls lxc_log_init with a logfile parameter. In this - * case we don't want lxc.logfile to override this. - * 3. When a lxc.logfile entry is found in config file. - */ -int do_lxc_log_set_file(const char *fname, int from_default) -{ - if (lxc_log_specified) { - INFO("lxc.logfile overridden by command line"); - return 0; - } - if (lxc_log_fd != -1) { - // we are overriding the default. - close(lxc_log_fd); - free(log_fname); - } - -#if USE_CONFIGPATH_LOGS - // we don't build_dir for the default if the default is - // i.e. /var/lib/lxc/$container/$container.log - if (!from_default) -#endif - if (build_dir(fname)) { - ERROR("failed to create dir for log file \"%s\" : %s", fname, - strerror(errno)); - return -1; - } - - lxc_log_fd = log_open(fname); - if (lxc_log_fd == -1) - return -1; - - log_fname = strdup(fname); - return 0; -} - -extern int lxc_log_set_file(const char *fname) -{ - return do_lxc_log_set_file(fname, 0); -} - extern int lxc_log_get_level(void) { if (!lxc_loglevel_specified) @@ -345,7 +357,30 @@ extern int lxc_log_get_level(void) return lxc_log_category_lxc.priority; } +/* + * This is called when we read a lxc.logfile entry in a lxc.conf file. This + * happens after processing command line arguments, which override the .conf + * settings. So only set the file if previously unset. + */ +extern int lxc_log_set_file(const char *fname) +{ + if (lxc_logfile_specified) + return 0; + return __lxc_log_set_file(fname, 0); +} + extern const char *lxc_log_get_file(void) { return log_fname; } + +extern void lxc_log_set_prefix(const char *prefix) +{ + strncpy(log_prefix, prefix, sizeof(log_prefix)); + log_prefix[sizeof(log_prefix) - 1] = 0; +} + +extern const char *lxc_log_get_prefix(void) +{ + return log_prefix; +} diff --git a/src/lxc/log.h b/src/lxc/log.h index cd43068a8..2fd405000 100644 --- a/src/lxc/log.h +++ b/src/lxc/log.h @@ -288,11 +288,13 @@ extern struct lxc_log_category lxc_log_category_lxc; extern int lxc_log_fd; extern int lxc_log_init(const char *name, const char *file, - const char *priority, const char *prefix, int quiet); + const char *priority, const char *prefix, int quiet, + const char *lxcpath); -extern void lxc_log_setprefix(const char *a_prefix); -extern int lxc_log_set_level(int level); extern int lxc_log_set_file(const char *fname); -extern int lxc_log_get_level(void); +extern int lxc_log_set_level(int level); +extern void lxc_log_set_prefix(const char *prefix); extern const char *lxc_log_get_file(void); +extern int lxc_log_get_level(void); +extern const char *lxc_log_get_prefix(void); #endif diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c index d845e3c48..300bc922d 100644 --- a/src/lxc/lxc_attach.c +++ b/src/lxc/lxc_attach.c @@ -292,7 +292,7 @@ int main(int argc, char *argv[]) return ret; ret = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet); + my_args.progname, my_args.quiet, my_args.lxcpath); if (ret) return ret; diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index f7c88a89c..7684f1b1f 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -69,7 +69,7 @@ int main(int argc, char *argv[]) return -1; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + my_args.progname, my_args.quiet, my_args.lxcpath)) return -1; state_object = my_args.argv[0]; diff --git a/src/lxc/lxc_checkpoint.c b/src/lxc/lxc_checkpoint.c index 947d9d941..8b3a02abe 100644 --- a/src/lxc/lxc_checkpoint.c +++ b/src/lxc/lxc_checkpoint.c @@ -116,7 +116,7 @@ int main(int argc, char *argv[]) return ret; ret = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet); + my_args.progname, my_args.quiet, my_args.lxcpath); if (ret) return ret; diff --git a/src/lxc/lxc_console.c b/src/lxc/lxc_console.c index f6659f64e..1d779a161 100644 --- a/src/lxc/lxc_console.c +++ b/src/lxc/lxc_console.c @@ -192,7 +192,7 @@ int main(int argc, char *argv[]) return -1; err = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet); + my_args.progname, my_args.quiet, my_args.lxcpath); if (err) return -1; diff --git a/src/lxc/lxc_execute.c b/src/lxc/lxc_execute.c index 41e29aa9b..0fa2d2516 100644 --- a/src/lxc/lxc_execute.c +++ b/src/lxc/lxc_execute.c @@ -101,7 +101,7 @@ int main(int argc, char *argv[]) return -1; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + my_args.progname, my_args.quiet, my_args.lxcpath)) return -1; /* rcfile is specified in the cli option */ diff --git a/src/lxc/lxc_freeze.c b/src/lxc/lxc_freeze.c index b52ab5bf1..ff3cdd577 100644 --- a/src/lxc/lxc_freeze.c +++ b/src/lxc/lxc_freeze.c @@ -55,7 +55,7 @@ int main(int argc, char *argv[]) return -1; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + my_args.progname, my_args.quiet, my_args.lxcpath)) return -1; return lxc_freeze(my_args.name, my_args.lxcpath); diff --git a/src/lxc/lxc_info.c b/src/lxc/lxc_info.c index 3fcead583..b19b1d02f 100644 --- a/src/lxc/lxc_info.c +++ b/src/lxc/lxc_info.c @@ -80,7 +80,7 @@ int main(int argc, char *argv[]) return 1; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + my_args.progname, my_args.quiet, my_args.lxcpath)) return 1; if (!state && !pid) diff --git a/src/lxc/lxc_init.c b/src/lxc/lxc_init.c index 84e12932e..663875b37 100644 --- a/src/lxc/lxc_init.c +++ b/src/lxc/lxc_init.c @@ -78,7 +78,7 @@ int main(int argc, char *argv[]) if (lxc_caps_init()) exit(err); - if (lxc_log_init(NULL, "none", 0, basename(argv[0]), quiet)) + if (lxc_log_init(NULL, "none", 0, basename(argv[0]), quiet, NULL)) exit(err); if (!argv[optind]) { diff --git a/src/lxc/lxc_kill.c b/src/lxc/lxc_kill.c index ba00aa8c1..e08993139 100644 --- a/src/lxc/lxc_kill.c +++ b/src/lxc/lxc_kill.c @@ -62,7 +62,7 @@ int main(int argc, char *argv[], char *envp[]) return ret; ret = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet); + my_args.progname, my_args.quiet, my_args.lxcpath); if (ret) return ret; diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c index 0ca829f67..5ddb2913a 100644 --- a/src/lxc/lxc_monitor.c +++ b/src/lxc/lxc_monitor.c @@ -66,7 +66,7 @@ int main(int argc, char *argv[]) return -1; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + my_args.progname, my_args.quiet, my_args.lxcpath)) return -1; len = strlen(my_args.name) + 3; diff --git a/src/lxc/lxc_monitord.c b/src/lxc/lxc_monitord.c index 3b5cf53b1..e76af716b 100644 --- a/src/lxc/lxc_monitord.c +++ b/src/lxc/lxc_monitord.c @@ -343,7 +343,7 @@ int main(int argc, char *argv[]) if (ret < 0 || ret >= sizeof(logpath)) return EXIT_FAILURE; - ret = lxc_log_init(NULL, logpath, "NOTICE", "lxc-monitord", 0); + ret = lxc_log_init(NULL, logpath, "NOTICE", "lxc-monitord", 0, lxcpath); if (ret) return ret; diff --git a/src/lxc/lxc_restart.c b/src/lxc/lxc_restart.c index 118d4b879..77099b149 100644 --- a/src/lxc/lxc_restart.c +++ b/src/lxc/lxc_restart.c @@ -124,7 +124,7 @@ int main(int argc, char *argv[]) return -1; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + my_args.progname, my_args.quiet, my_args.lxcpath)) return -1; /* rcfile is specified in the cli option */ diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c index 957fdb0e7..d923a7eb5 100644 --- a/src/lxc/lxc_start.c +++ b/src/lxc/lxc_start.c @@ -165,7 +165,7 @@ int main(int argc, char *argv[]) args = my_args.argv; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + my_args.progname, my_args.quiet, my_args.lxcpath)) return err; /* rcfile is specified in the cli option */ diff --git a/src/lxc/lxc_stop.c b/src/lxc/lxc_stop.c index b4d9f23dd..0967a156f 100644 --- a/src/lxc/lxc_stop.c +++ b/src/lxc/lxc_stop.c @@ -55,7 +55,7 @@ int main(int argc, char *argv[]) return -1; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + my_args.progname, my_args.quiet, my_args.lxcpath)) return -1; return lxc_stop(my_args.name, my_args.lxcpath); diff --git a/src/lxc/lxc_unfreeze.c b/src/lxc/lxc_unfreeze.c index 0bb5dc502..44d3cc021 100644 --- a/src/lxc/lxc_unfreeze.c +++ b/src/lxc/lxc_unfreeze.c @@ -54,7 +54,7 @@ int main(int argc, char *argv[]) return -1; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + my_args.progname, my_args.quiet, my_args.lxcpath)) return -1; return lxc_unfreeze(my_args.name, my_args.lxcpath); diff --git a/src/lxc/lxc_wait.c b/src/lxc/lxc_wait.c index 18200e574..d21578b6c 100644 --- a/src/lxc/lxc_wait.c +++ b/src/lxc/lxc_wait.c @@ -84,7 +84,7 @@ int main(int argc, char *argv[]) return -1; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + my_args.progname, my_args.quiet, my_args.lxcpath)) return -1; return lxc_wait(strdup(my_args.name), my_args.states, my_args.timeout, my_args.lxcpath); diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 53765b04c..740a8d99e 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1105,7 +1105,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath c->set_config_path = lxcapi_set_config_path; /* we'll allow the caller to update these later */ - if (lxc_log_init(NULL, "none", NULL, "lxc_container", 0)) { + if (lxc_log_init(NULL, "none", NULL, "lxc_container", 0, c->config_path)) { fprintf(stderr, "failed to open log\n"); goto err; }