Add 'lxc.logfile' and 'lxc.loglevel' config items. Values provided on the command line override the config items.
Have lxccontainer not set a default loglevel and logfile. Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com> --- src/lxc/conf.c | 3 +++ src/lxc/conf.h | 3 +++ src/lxc/confile.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++- src/lxc/log.c | 38 +++++++++++++++++++++++++++++++ src/lxc/log.h | 4 +++- src/lxc/lxccontainer.c | 2 +- 6 files changed, 105 insertions(+), 3 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 65e19a9..79d96d7 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -1877,6 +1877,7 @@ struct lxc_conf *lxc_conf_init(void) new->console.slave = -1; new->console.name[0] = '\0'; new->rootfs.mount = default_rootfs_mount; + new->loglevel = LXC_LOG_PRIORITY_NOTSET; lxc_list_init(&new->cgroup); lxc_list_init(&new->network); lxc_list_init(&new->mount_list); @@ -2725,6 +2726,8 @@ void lxc_conf_free(struct lxc_conf *conf) free(conf->ttydir); if (conf->fstab) free(conf->fstab); + if (conf->logfile) + free(conf->logfile); lxc_clear_config_network(conf); #if HAVE_APPARMOR if (conf->aa_profile) diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 535823d..694bce4 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -232,6 +232,9 @@ struct lxc_conf { #if HAVE_APPARMOR char *aa_profile; #endif + char *logfile; + int loglevel; + #if HAVE_APPARMOR /* || HAVE_SELINUX || HAVE_SMACK */ int lsm_umount_proc; #endif diff --git a/src/lxc/confile.c b/src/lxc/confile.c index bc55f8c..a64ae09 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -55,6 +55,8 @@ static int config_ttydir(const char *, const char *, struct lxc_conf *); static int config_aa_profile(const char *, const char *, struct lxc_conf *); #endif static int config_cgroup(const char *, const char *, struct lxc_conf *); +static int config_loglevel(const char *, const char *, struct lxc_conf *); +static int config_logfile(const char *, const char *, struct lxc_conf *); static int config_mount(const char *, const char *, struct lxc_conf *); static int config_rootfs(const char *, const char *, struct lxc_conf *); static int config_rootfs_mount(const char *, const char *, struct lxc_conf *); @@ -92,6 +94,8 @@ static struct lxc_config_t config[] = { { "lxc.aa_profile", config_aa_profile }, #endif { "lxc.cgroup", config_cgroup }, + { "lxc.loglevel", config_loglevel }, + { "lxc.logfile", config_logfile }, { "lxc.mount", config_mount }, { "lxc.rootfs.mount", config_rootfs_mount }, { "lxc.rootfs", config_rootfs }, @@ -903,6 +907,51 @@ static int config_aa_profile(const char *key, const char *value, } #endif +static int config_logfile(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + char *path; + + // if given a blank entry, null out any previous entries. + if (!value || strlen(value) == 0) { + if (lxc_conf->logfile) { + free(lxc_conf->logfile); + lxc_conf->logfile = NULL; + } + return 0; + } + + path = strdup(value); + if (!path) { + SYSERROR("failed to strdup '%s': %m", value); + return -1; + } + + if (lxc_log_set_file(path)) { + free(path); + return -1; + } + + if (lxc_conf->logfile) + free(lxc_conf->logfile); + lxc_conf->logfile = path; + + return 0; +} + +static int config_loglevel(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + if (!value || strlen(value) == 0) + return 0; + + if (value[0] >= '0' && value[0] <= '9') + lxc_conf->loglevel = atoi(value); + else + lxc_conf->loglevel = lxc_log_priority_to_int(value); + return lxc_log_set_level(lxc_conf->loglevel); +} + static int config_autodev(const char *key, const char *value, struct lxc_conf *lxc_conf) { @@ -1526,7 +1575,7 @@ static int lxc_get_item_network(struct lxc_conf *c, char *retv, int inlen) int lxc_get_config_item(struct lxc_conf *c, const char *key, char *retv, int inlen) { - char *v = NULL; + const char *v = NULL; if (strcmp(key, "lxc.mount.entry") == 0) return lxc_get_mount_entries(c, retv, inlen); @@ -1544,6 +1593,10 @@ int lxc_get_config_item(struct lxc_conf *c, const char *key, char *retv, else if (strcmp(key, "lxc.aa_profile") == 0) v = c->aa_profile; #endif + else if (strcmp(key, "lxc.logfile") == 0) + v = c->logfile; + else if (strcmp(key, "lxc.loglevel") == 0) + v = lxc_log_priority_to_string(c->loglevel); else if (strcmp(key, "lxc.cgroup") == 0) // all cgroup info return lxc_get_cgroup_entry(c, retv, inlen, "all"); else if (strncmp(key, "lxc.cgroup.", 11) == 0) // specific cgroup info @@ -1621,6 +1674,9 @@ void write_config(FILE *fout, struct lxc_conf *c) if (c->aa_profile) fprintf(fout, "lxc.aa_profile = %s\n", c->aa_profile); #endif + fprintf(fout, "lxc.loglevel = %s\n", lxc_log_priority_to_string(c->loglevel)); + if (c->logfile) + fprintf(fout, "lxc.logfile = %s\n", c->logfile); lxc_list_for_each(it, &c->cgroup) { struct lxc_cgroup *cg = it->elem; fprintf(fout, "lxc.cgroup.%s = %s\n", cg->subsystem, cg->value); diff --git a/src/lxc/log.c b/src/lxc/log.c index 02ee21c..0354d8d 100644 --- a/src/lxc/log.c +++ b/src/lxc/log.c @@ -41,6 +41,7 @@ int lxc_log_fd = -1; static char log_prefix[LXC_LOG_PREFIX_SIZE] = "lxc"; +int lxc_loglevel_specified = 0; lxc_log_define(lxc_log, lxc); @@ -157,6 +158,7 @@ extern int lxc_log_init(const char *file, const char *priority, return 0; if (priority) { + lxc_loglevel_specified = 1; lxc_priority = lxc_log_priority_to_int(priority); if (lxc_priority == LXC_LOG_PRIORITY_NOTSET) { @@ -188,3 +190,39 @@ extern int lxc_log_init(const char *file, const char *priority, return 0; } + +/* + * This is called when we read a lxc.loglevel entry in a lxc.conf file. This + * happens after processing command line arguments, which override the .conf + * settings. So only set the level if previously unset. + */ +extern int lxc_log_set_level(int level) +{ + if (lxc_loglevel_specified) + return 0; + if (level < 0 || level >= LXC_LOG_PRIORITY_NOTSET) { + ERROR("invalid log priority %d", level); + return -1; + } + lxc_log_category_lxc.priority = level; + return 0; +} + +/* + * 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 logfile if previously unset. + */ +extern int lxc_log_set_file(char *fname) +{ + if (lxc_log_fd != -1) { + INFO("Configuration file was specified on command line, configuration file entry being ignored"); + return 0; + } + lxc_log_fd = log_open(fname); + if (lxc_log_fd == -1) { + ERROR("failed to open log file %s\n", fname); + return -1; + } + return 0; +} diff --git a/src/lxc/log.h b/src/lxc/log.h index b11093d..340a3ab 100644 --- a/src/lxc/log.h +++ b/src/lxc/log.h @@ -41,7 +41,7 @@ #define LXC_LOG_BUFFER_SIZE 512 /* predefined priorities. */ -enum { +enum lxc_loglevel { LXC_LOG_PRIORITY_TRACE, LXC_LOG_PRIORITY_DEBUG, LXC_LOG_PRIORITY_INFO, @@ -291,4 +291,6 @@ extern int lxc_log_init(const char *file, const char *priority, const char *prefix, int quiet); extern void lxc_log_setprefix(const char *a_prefix); +extern int lxc_log_set_level(int level); +extern int lxc_log_set_file(char *fname); #endif diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index e41fd0d..d25b848 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -922,7 +922,7 @@ struct lxc_container *lxc_container_new(const char *name) c->get_config_item = lxcapi_get_config_item; /* we'll allow the caller to update these later */ - if (lxc_log_init("/var/log/lxccontainer.log", "trace", "lxc_container", 0)) { + if (lxc_log_init(NULL, NULL, "lxc_container", 0)) { fprintf(stderr, "failed to open log\n"); goto err; } -- 1.7.10.4 ------------------------------------------------------------------------------ LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel