[lxc-devel] [PATCH RFC] lxc_conf logfile and loglevel support

Stéphane Graber stgraber at ubuntu.com
Tue Dec 4 16:26:16 UTC 2012


On 12/03/2012 08:41 PM, Serge Hallyn wrote:
> 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.hallyn at ubuntu.com>

Haven't tested it but the code matches what I think we should be doing.

Acked-by: Stéphane Graber <stgraber at 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;
>  	}
> 


-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 899 bytes
Desc: OpenPGP digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20121204/3b2f4879/attachment.pgp>


More information about the lxc-devel mailing list