[lxc-devel] [PATCH] Switch from use of LXCPATH to a configurable default_lxc_path

Stéphane Graber stgraber at ubuntu.com
Fri Feb 8 15:53:27 UTC 2013


On 02/06/2013 04:11 PM, Serge Hallyn wrote:
> Here is a patch to introduce a configurable system-wide
> lxcpath.  It seems to work with lxc-create, lxc-start,
> and basic python3 lxc usage through the api.
> 
> For shell functions, a new /usr/share/lxc/lxc.functions is
> introduced which sets some of the basic global variables,
> including evaluating the right place for lxc_path.
> 
> I have not converted any of the other python code, as I was
> not sure where we should keep the common functions (i.e.
> for now just default_lxc_path()).
> 
> configure.ac: add an option for setting the global config file name.
> utils: add a default_lxc_path() function
> Use default_lxc_path in .c files
> define get_lxc_path() and set_lxc_path() in C api
> use get_lxc_path() in lua api
> create sh helper for getting default path from config file
> fix up scripts to use lxc.functions
> 
> Changelog:
>   feb6:
> 	fix lxc_path in lxc.functions
> 	utils.c: as Dwight pointed out, don't close a NULL fin.
> 	utils.c: fix the parsing of lxcpath line
> 	lxc-start: print which rcfile we are using
> 	commands.c: As Dwight alluded to, the sockname handling was just
> 	   ridiculous.  Clean that up.
> 	use Dwight's recommendation for lxc.functions path: $datadir/lxc
> 	make lxccontainer->get_config_path() return const char *
> 		Per Dwight's suggestion, much nicer than returning strdup.
>   feb6 (v2):
>         lxccontainer: set c->config_path before using it.
> 	convert legacy lxc-ls
> 
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>

Looks good to me.

Acked-by: Stéphane Graber <stgraber at ubuntu.com>

I'll update the python binding and send the result to the mailing-list.

> ---
>  configure.ac             | 11 +++++++++
>  src/lua-lxc/core.c       |  6 ++++-
>  src/lxc/Makefile.am      |  6 +++++
>  src/lxc/commands.c       | 32 +++++++++++++++++---------
>  src/lxc/conf.c           | 12 ++++++++--
>  src/lxc/legacy/lxc-ls.in |  2 +-
>  src/lxc/lxc-clone.in     |  3 +--
>  src/lxc/lxc-create.in    |  4 +---
>  src/lxc/lxc-destroy.in   |  2 +-
>  src/lxc/lxc-setcap.in    | 28 +++++++++++-----------
>  src/lxc/lxc-setuid.in    | 48 +++++++++++++++++++-------------------
>  src/lxc/lxc.functions.in | 35 ++++++++++++++++++++++++++++
>  src/lxc/lxc_execute.c    |  9 +++++++-
>  src/lxc/lxc_restart.c    |  9 +++++++-
>  src/lxc/lxc_start.c      |  9 +++++++-
>  src/lxc/lxccontainer.c   | 60 ++++++++++++++++++++++++++++++++++++++++--------
>  src/lxc/lxccontainer.h   | 14 +++++++++++
>  src/lxc/utils.c          | 56 ++++++++++++++++++++++++++++++++++++++++++++
>  src/lxc/utils.h          |  5 ++++
>  src/tests/Makefile.am    |  1 +
>  20 files changed, 282 insertions(+), 70 deletions(-)
>  create mode 100644 src/lxc/lxc.functions.in
> 
> diff --git a/configure.ac b/configure.ac
> index 359f28d..3e82a65 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -161,12 +161,21 @@ AC_ARG_ENABLE([tests],
>  AM_CONDITIONAL([ENABLE_TESTS], [test "x$enable_tests" = "xyes"])
>  
>  # LXC container path, where the containers are actually stored
> +# This is overriden by an entry in the file called LXCCONF
> +# (i.e. /etc/lxc/lxc.conf)
>  AC_ARG_WITH([config-path],
>  	[AC_HELP_STRING(
>  		[--with-config-path=dir],
>  		[lxc configuration repository path]
>  	)], [], [with_config_path=['${localstatedir}/lib/lxc']])
>  
> +# The path of the global lxc configuration file.
> +AC_ARG_WITH([global-conf],
> +	[AC_HELP_STRING(
> +		[--with-global-conf=dir],
> +		[global lxc configuration file]
> +	)], [], [with_global_conf=['${sysconfdir}/lxc/lxc.conf']])
> +
>  # Rootfs path, where the container mount structure is assembled
>  AC_ARG_WITH([rootfs-path],
>  	[AC_HELP_STRING(
> @@ -207,6 +216,7 @@ AS_AC_EXPAND(DOCDIR, "$docdir")
>  AS_AC_EXPAND(LXC_CONFFILE, "$conffile")
>  AS_AC_EXPAND(LXC_GENERATE_DATE, "$(date)")
>  AS_AC_EXPAND(LXCPATH, "$with_config_path")
> +AS_AC_EXPAND(LXC_GLOBAL_CONF, "$with_global_conf")
>  AS_AC_EXPAND(LXCROOTFSMOUNT, "$with_rootfs_path")
>  AS_AC_EXPAND(LXCTEMPLATEDIR, "$datadir/lxc/templates")
>  AS_AC_EXPAND(LXCINITDIR, "$libexecdir")
> @@ -355,6 +365,7 @@ AC_CONFIG_FILES([
>  	src/lxc/lxc-start-ephemeral
>  	src/lxc/lxc-destroy
>  	src/lxc/legacy/lxc-ls
> +	src/lxc/lxc.functions
>  
>  	src/python-lxc/Makefile
>  	src/python-lxc/lxc/__init__.py
> diff --git a/src/lua-lxc/core.c b/src/lua-lxc/core.c
> index 5c47aed..ae4d9b2 100644
> --- a/src/lua-lxc/core.c
> +++ b/src/lua-lxc/core.c
> @@ -339,7 +339,11 @@ static int lxc_version_get(lua_State *L) {
>  }
>  
>  static int lxc_path_get(lua_State *L) {
> -    lua_pushstring(L, LXCPATH);
> +    struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
> +    const char *lxcpath;
> +
> +    lxcpath = c->get_config_path(c);
> +    lua_pushstring(L, lxcpath);
>      return 1;
>  }
>  
> diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
> index d8506d3..bada939 100644
> --- a/src/lxc/Makefile.am
> +++ b/src/lxc/Makefile.am
> @@ -88,6 +88,7 @@ endif
>  AM_CFLAGS=-I$(top_srcdir)/src \
>  	-DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \
>  	-DLXCPATH=\"$(LXCPATH)\" \
> +	-DLXC_GLOBAL_CONF=\"$(LXC_GLOBAL_CONF)\" \
>  	-DLXCINITDIR=\"$(LXCINITDIR)\" \
>  	-DLXCTEMPLATEDIR=\"$(LXCTEMPLATEDIR)\" \
>  	-DLOGPATH=\"$(LOGPATH)\"
> @@ -164,6 +165,9 @@ bin_PROGRAMS = \
>  pkglibexec_PROGRAMS = \
>  	lxc-init
>  
> +#pkglibexec_SCRIPTS = \
> +#	lxc.functions
> +
>  AM_LDFLAGS = -Wl,-E
>  if ENABLE_RPATH
>  AM_LDFLAGS += -Wl,-rpath -Wl,$(libdir)
> @@ -192,6 +196,8 @@ lxc_wait_SOURCES = lxc_wait.c
>  lxc_kill_SOURCES = lxc_kill.c
>  
>  install-exec-local: install-soPROGRAMS
> +	mkdir -p $(DESTDIR)$(datadir)/lxc
> +	install -c -m 644 lxc.functions $(DESTDIR)$(datadir)/lxc
>  	mv $(DESTDIR)$(libdir)/liblxc.so $(DESTDIR)$(libdir)/liblxc.so.$(VERSION)
>  	/sbin/ldconfig -l $(DESTDIR)$(libdir)/liblxc.so.$(VERSION)
>  	cd $(DESTDIR)$(libdir); \
> diff --git a/src/lxc/commands.c b/src/lxc/commands.c
> index 40c685e..2c4d603 100644
> --- a/src/lxc/commands.c
> +++ b/src/lxc/commands.c
> @@ -30,10 +30,13 @@
>  #include <sys/un.h>
>  #include <sys/poll.h>
>  #include <sys/param.h>
> +#include <malloc.h>
> +#include <stdlib.h>
>  
>  #include <lxc/log.h>
>  #include <lxc/conf.h>
>  #include <lxc/start.h>	/* for struct lxc_handler */
> +#include <lxc/utils.h>
>  
>  #include "commands.h"
>  #include "mainloop.h"
> @@ -56,7 +59,20 @@
>  
>  lxc_log_define(lxc_commands, lxc);
>  
> -#define abstractname LXCPATH "/%s/command"
> +static int fill_sock_name(char *path, int len, const char *name) {
> +	char *lxcpath = default_lxc_path();
> +	int ret;
> +	if (!lxcpath) {
> +		ERROR("Out of memory getting lxcpath");
> +		return -1;
> +	}
> +	ret = snprintf(path, len, "%s/%s/command", lxcpath, name);
> +	if (ret < 0 || ret >= len) {
> +		ERROR("Name too long");
> +		return -1;
> +	}
> +	return 0;
> +}
>  
>  static int receive_answer(int sock, struct lxc_answer *answer)
>  {
> @@ -75,14 +91,11 @@ static int __lxc_command(const char *name, struct lxc_command *command,
>  	int sock, ret = -1;
>  	char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 };
>  	char *offset = &path[1];
> -	int rc, len;
> +	int len;
>  
>  	len = sizeof(path)-1;
> -	rc = snprintf(offset, len, abstractname, name);
> -	if (rc < 0 || rc >= len) {
> -		ERROR("Name too long");
> +	if (fill_sock_name(offset, len, name))
>  		return -1;
> -	}
>  
>  	sock = lxc_af_unix_connect(path);
>  	if (sock < 0 && errno == ECONNREFUSED) {
> @@ -292,14 +305,11 @@ extern int lxc_command_init(const char *name, struct lxc_handler *handler)
>  	int fd;
>  	char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 };
>  	char *offset = &path[1];
> -	int rc, len;
> +	int len;
>  
>  	len = sizeof(path)-1;
> -	rc = snprintf(offset, len, abstractname, name);
> -	if (rc < 0 || rc >= len) {
> -		ERROR("Name too long");
> +	if (fill_sock_name(offset, len, name))
>  		return -1;
> -	}
>  
>  	fd = lxc_af_unix_open(path, SOCK_STREAM, 0);
>  	if (fd < 0) {
> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index 63f5567..bb93189 100644
> --- a/src/lxc/conf.c
> +++ b/src/lxc/conf.c
> @@ -1519,15 +1519,23 @@ static int mount_entry_on_absolute_rootfs(struct mntent *mntent,
>  	unsigned long mntflags;
>  	char *mntdata;
>  	int r, ret = 0, offset;
> +	char *lxcpath;
>  
>  	if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
>  		ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
>  		return -1;
>  	}
>  
> +	lxcpath = default_lxc_path();
> +	if (!lxcpath) {
> +		ERROR("Out of memory");
> +		return -1;
> +	}
> +
>  	/* if rootfs->path is a blockdev path, allow container fstab to
> -	 * use $LXCPATH/CN/rootfs as the target prefix */
> -	r = snprintf(path, MAXPATHLEN, LXCPATH "/%s/rootfs", lxc_name);
> +	 * use $lxcpath/CN/rootfs as the target prefix */
> +	r = snprintf(path, MAXPATHLEN, "%s/%s/rootfs", lxcpath, lxc_name);
> +	free(lxcpath);
>  	if (r < 0 || r >= MAXPATHLEN)
>  		goto skipvarlib;
>  
> diff --git a/src/lxc/legacy/lxc-ls.in b/src/lxc/legacy/lxc-ls.in
> index 7a298c6..ec73c8f 100644
> --- a/src/lxc/legacy/lxc-ls.in
> +++ b/src/lxc/legacy/lxc-ls.in
> @@ -17,7 +17,7 @@
>  # License along with this library; if not, write to the Free Software
>  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
>  
> -lxc_path=@LXCPATH@
> +. @DATADIR@/lxc/lxc.functions
>  
>  usage()
>  {
> diff --git a/src/lxc/lxc-clone.in b/src/lxc/lxc-clone.in
> index 860b86f..fcf34a9 100755
> --- a/src/lxc/lxc-clone.in
> +++ b/src/lxc/lxc-clone.in
> @@ -54,8 +54,7 @@ optarg_check() {
>      [ -n "$2" ] || usage_err "option $1 requires an argument"
>  }
>  
> -lxc_path=@LXCPATH@
> -bindir=@BINDIR@
> +. @DATADIR@/lxc/lxc.functions
>  snapshot=no
>  lxc_defsize=2G
>  lxc_size=_unset
> diff --git a/src/lxc/lxc-create.in b/src/lxc/lxc-create.in
> index 9348d87..02e54a6 100644
> --- a/src/lxc/lxc-create.in
> +++ b/src/lxc/lxc-create.in
> @@ -73,9 +73,7 @@ optarg_check() {
>      fi
>  }
>  
> -lxc_path=@LXCPATH@
> -bindir=@BINDIR@
> -templatedir=@LXCTEMPLATEDIR@
> +. @DATADIR@/lxc/lxc.functions
>  backingstore=_unset
>  fstype=ext4
>  fssize=500M
> diff --git a/src/lxc/lxc-destroy.in b/src/lxc/lxc-destroy.in
> index 497acbe..6464e52 100644
> --- a/src/lxc/lxc-destroy.in
> +++ b/src/lxc/lxc-destroy.in
> @@ -51,7 +51,7 @@ optarg_check() {
>      fi
>  }
>  
> -lxc_path=@LXCPATH@
> +. @DATADIR@/lxc/lxc.functions
>  force=0
>  
>  while [ $# -gt 0 ]; do
> diff --git a/src/lxc/lxc-setcap.in b/src/lxc/lxc-setcap.in
> index 3e95b16..f338f12 100644
> --- a/src/lxc/lxc-setcap.in
> +++ b/src/lxc/lxc-setcap.in
> @@ -25,6 +25,8 @@
>  # When the capabilities are set, a non root user can manage the containers.
>  #
>  
> +. @DATADIR@/lxc/lxc.functions
> +
>  LXC_ATTACH_CAPS="cap_sys_admin,cap_dac_override"
>  LXC_CREATE_CAPS="cap_sys_admin"
>  LXC_NETSTAT_CAPS="cap_sys_admin"
> @@ -62,23 +64,23 @@ lxc_setcaps()
>      setcap $LXC_CHECKPOINT_CAPS=ep @BINDIR@/lxc-checkpoint
>      setcap $LXC_INIT_CAPS=ep @LXCINITDIR@/lxc/lxc-init
>  
> -    test -e @LXCPATH@ || mkdir -p @LXCPATH@
> -    chmod 0777 @LXCPATH@
> +    test -e $lxc_path || mkdir -p $lxc_path
> +    chmod 0777 $lxc_path
>  }
>  
>  lxc_dropcaps()
>  {
> -    setcap -r @BINDIR@/lxc-attach
> -    setcap -r @BINDIR@/lxc-create
> -    setcap -r @BINDIR@/lxc-execute
> -    setcap -r @BINDIR@/lxc-start
> -    setcap -r @BINDIR@/lxc-restart
> -    setcap -r @BINDIR@/lxc-unshare
> -    setcap -r @BINDIR@/lxc-netstat
> -    setcap -r @BINDIR@/lxc-checkpoint
> -    setcap -r @LXCINITDIR@/lxc/lxc-init
> -
> -    chmod 0755 @LXCPATH@
> +    setcap -r $bindir/lxc-attach
> +    setcap -r $bindir/lxc-create
> +    setcap -r $bindir/lxc-execute
> +    setcap -r $bindir/lxc-start
> +    setcap -r $bindir/lxc-restart
> +    setcap -r $bindir/lxc-unshare
> +    setcap -r $bindir/lxc-netstat
> +    setcap -r $bindir/lxc-checkpoint
> +    setcap -r $lxcinitdir/lxc/lxc-init
> +
> +    chmod 0755 $lxc_path
>  }
>  
>  usage_err() {
> diff --git a/src/lxc/lxc-setuid.in b/src/lxc/lxc-setuid.in
> index 4e92bb0..2e44b8d 100644
> --- a/src/lxc/lxc-setuid.in
> +++ b/src/lxc/lxc-setuid.in
> @@ -25,6 +25,8 @@
>  # When the capabilities are set, a non root user can manage the containers.
>  #
>  
> +. @DATADIR@/lxc/lxc.functions
> +
>  usage() {
>      echo "usage: $(basename $0) [-d]" >&2
>  }
> @@ -49,33 +51,33 @@ setuid()
>  
>  lxc_setuid()
>  {
> -    setuid @BINDIR@/lxc-attach
> -    setuid @BINDIR@/lxc-create
> -    setuid @BINDIR@/lxc-execute
> -    setuid @BINDIR@/lxc-start
> -    setuid @BINDIR@/lxc-restart
> -    setuid @BINDIR@/lxc-unshare
> -    setuid @BINDIR@/lxc-netstat
> -    setuid @BINDIR@/lxc-checkpoint
> -    setuid @LXCINITDIR@/lxc-init
> -
> -    test -e @LXCPATH@ || mkdir -p @LXCPATH@
> -    chmod 0777 @LXCPATH@
> +    setuid $bindir/lxc-attach
> +    setuid $bindir/lxc-create
> +    setuid $bindir/lxc-execute
> +    setuid $bindir/lxc-start
> +    setuid $bindir/lxc-restart
> +    setuid $bindir/lxc-unshare
> +    setuid $bindir/lxc-netstat
> +    setuid $bindir/lxc-checkpoint
> +    setuid $lxcinitdir/lxc-init
> +
> +    test -e $lxc_path || mkdir -p $lxc_path
> +    chmod 0777 $lxc_path
>  }
>  
>  lxc_dropuid()
>  {
> -    setuid -r @BINDIR@/lxc-attach
> -    setuid -r @BINDIR@/lxc-create
> -    setuid -r @BINDIR@/lxc-execute
> -    setuid -r @BINDIR@/lxc-start
> -    setuid -r @BINDIR@/lxc-restart
> -    setuid -r @BINDIR@/lxc-unshare
> -    setuid -r @BINDIR@/lxc-netstat
> -    setuid -r @BINDIR@/lxc-checkpoint
> -    setuid -r @LXCINITDIR@/lxc-init
> -
> -    chmod 0755 @LXCPATH@
> +    setuid -r $bindir/lxc-attach
> +    setuid -r $bindir/lxc-create
> +    setuid -r $bindir/lxc-execute
> +    setuid -r $bindir/lxc-start
> +    setuid -r $bindir/lxc-restart
> +    setuid -r $bindir/lxc-unshare
> +    setuid -r $bindir/lxc-netstat
> +    setuid -r $bindir/lxc-checkpoint
> +    setuid -r $lxcinitdir/lxc-init
> +
> +    chmod 0755 $lxc_path
>  }
>  
>  usage_err() {
> diff --git a/src/lxc/lxc.functions.in b/src/lxc/lxc.functions.in
> new file mode 100644
> index 0000000..3425929
> --- /dev/null
> +++ b/src/lxc/lxc.functions.in
> @@ -0,0 +1,35 @@
> +#!/bin/sh
> +
> +#
> +# lxc: linux Container library
> +
> +# Authors:
> +# Serge Hallyn <serge.hallyn at ubuntu.com>
> +
> +# This library is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU Lesser General Public
> +# License as published by the Free Software Foundation; either
> +# version 2.1 of the License, or (at your option) any later version.
> +
> +# This library is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +# Lesser General Public License for more details.
> +
> +# You should have received a copy of the GNU Lesser General Public
> +# License along with this library; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +
> +# This file contains helpers for the various lxc shell scripts
> +
> +globalconf=@LXC_GLOBAL_CONF@
> +bindir=@BINDIR@
> +templatedir=@LXCTEMPLATEDIR@
> +lxcinitdir=@LXCINITDIR@
> +
> +get_default_lxcpath() {
> +        (grep -v "^#" "$globalconf" 2>/dev/null || echo "lxcpath=@LXCPATH@") | \
> +                grep "[ \t]*lxcpath[ \t]*=" | awk -F= '{ print $2 }'
> +}
> +
> +lxc_path=`get_default_lxcpath`
> diff --git a/src/lxc/lxc_execute.c b/src/lxc/lxc_execute.c
> index 9377f4f..7a926a2 100644
> --- a/src/lxc/lxc_execute.c
> +++ b/src/lxc/lxc_execute.c
> @@ -39,6 +39,7 @@
>  #include "arguments.h"
>  #include "config.h"
>  #include "start.h"
> +#include "utils.h"
>  
>  lxc_log_define(lxc_execute_ui, lxc_execute);
>  
> @@ -108,8 +109,14 @@ int main(int argc, char *argv[])
>  		rcfile = (char *)my_args.rcfile;
>  	else {
>  		int rc;
> +		char *lxcpath = default_lxc_path();
> +		if (!lxcpath) {
> +			ERROR("Out of memory");
> +			return -1;
> +		}
>  
> -		rc = asprintf(&rcfile, LXCPATH "/%s/config", my_args.name);
> +		rc = asprintf(&rcfile, "%s/%s/config", lxcpath, my_args.name);
> +		free(lxcpath);
>  		if (rc == -1) {
>  			SYSERROR("failed to allocate memory");
>  			return -1;
> diff --git a/src/lxc/lxc_restart.c b/src/lxc/lxc_restart.c
> index 1cf9462..7561b1b 100644
> --- a/src/lxc/lxc_restart.c
> +++ b/src/lxc/lxc_restart.c
> @@ -36,6 +36,7 @@
>  #include "config.h"
>  #include "confile.h"
>  #include "arguments.h"
> +#include "utils.h"
>  
>  lxc_log_define(lxc_restart_ui, lxc_restart);
>  
> @@ -131,8 +132,14 @@ int main(int argc, char *argv[])
>  		rcfile = (char *)my_args.rcfile;
>  	else {
>  		int rc;
> +		char *lxcpath = default_lxc_path();
> +		if (!lxcpath) {
> +			ERROR("Out of memory");
> +			return -1;
> +		}
>  
> -		rc = asprintf(&rcfile, LXCPATH "/%s/config", my_args.name);
> +		rc = asprintf(&rcfile, "%s/%s/config", lxcpath, my_args.name);
> +		free(lxcpath);
>  		if (rc == -1) {
>  			SYSERROR("failed to allocate memory");
>  			return -1;
> diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c
> index b64acff..c50c36b 100644
> --- a/src/lxc/lxc_start.c
> +++ b/src/lxc/lxc_start.c
> @@ -173,8 +173,15 @@ int main(int argc, char *argv[])
>  		rcfile = (char *)my_args.rcfile;
>  	else {
>  		int rc;
> +		char *lxcpath = default_lxc_path();
> +		if (!lxcpath) {
> +			ERROR("Out of memory");
> +			return -1;
> +		}
>  
> -		rc = asprintf(&rcfile, LXCPATH "/%s/config", my_args.name);
> +		rc = asprintf(&rcfile, "%s/%s/config", lxcpath, my_args.name);
> +		INFO("using rcfile %s", rcfile);
> +		free(lxcpath);
>  		if (rc == -1) {
>  			SYSERROR("failed to allocate memory");
>  			return err;
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index 502a7a7..6ba77a8 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -30,6 +30,7 @@
>  #include <sys/types.h>
>  #include <sys/wait.h>
>  #include <errno.h>
> +#include <lxc/utils.h>
>  
>  lxc_log_define(lxc_container, lxc);
>  
> @@ -82,6 +83,10 @@ static void lxc_container_free(struct lxc_container *c)
>  		lxc_conf_free(c->lxc_conf);
>  		c->lxc_conf = NULL;
>  	}
> +	if (c->config_path) {
> +		free(c->config_path);
> +		c->config_path = NULL;
> +	}
>  	free(c);
>  }
>  
> @@ -483,11 +488,11 @@ static bool create_container_dir(struct lxc_container *c)
>  	char *s;
>  	int len, ret;
>  
> -	len = strlen(LXCPATH) + strlen(c->name) + 2;
> +	len = strlen(c->config_path) + strlen(c->name) + 2;
>  	s = malloc(len);
>  	if (!s)
>  		return false;
> -	ret = snprintf(s, len, "%s/%s", LXCPATH, c->name);
> +	ret = snprintf(s, len, "%s/%s", c->config_path, c->name);
>  	if (ret < 0 || ret >= len) {
>  		free(s);
>  		return false;
> @@ -577,11 +582,11 @@ static bool lxcapi_create(struct lxc_container *c, char *t, char *const argv[])
>  			exit(1);
>  		newargv[0] = t;
>  
> -		len = strlen(LXCPATH) + strlen(c->name) + strlen("--path=") + 2;
> +		len = strlen(c->config_path) + strlen(c->name) + strlen("--path=") + 2;
>  		patharg = malloc(len);
>  		if (!patharg)
>  			exit(1);
> -		ret = snprintf(patharg, len, "--path=%s/%s", LXCPATH, c->name);
> +		ret = snprintf(patharg, len, "--path=%s/%s", c->config_path, c->name);
>  		if (ret < 0 || ret >= len)
>  			exit(1);
>  		newargv[1] = patharg;
> @@ -859,6 +864,37 @@ static char *lxcapi_config_file_name(struct lxc_container *c)
>  	return strdup(c->configfile);
>  }
>  
> +static const char *lxcapi_get_config_path(struct lxc_container *c)
> +{
> +	if (!c || !c->config_path)
> +		return NULL;
> +	return (const char *)(c->config_path);
> +}
> +
> +static bool lxcapi_set_config_path(struct lxc_container *c, const char *path)
> +{
> +	char *p;
> +	bool b = false;
> +
> +	if (!c)
> +		return b;
> +
> +	if (lxclock(c->privlock, 0))
> +		return b;
> +
> +	p = strdup(path);
> +	if (!p)
> +		goto err;
> +	b = true;
> +	if (c->config_path)
> +		free(c->config_path);
> +	c->config_path = p;
> +err:
> +	lxcunlock(c->privlock);
> +	return b;
> +}
> +
> +
>  static bool lxcapi_set_cgroup_item(struct lxc_container *c, const char *subsys, const char *value)
>  {
>  	int ret;
> @@ -914,6 +950,12 @@ struct lxc_container *lxc_container_new(const char *name)
>  	}
>  	memset(c, 0, sizeof(*c));
>  
> +	c->config_path = default_lxc_path();
> +	if (!c->config_path) {
> +		fprintf(stderr, "Out of memory");
> +		goto err;
> +	}
> +
>  	c->name = malloc(strlen(name)+1);
>  	if (!c->name) {
>  		fprintf(stderr, "Error allocating lxc_container name\n");
> @@ -934,13 +976,13 @@ struct lxc_container *lxc_container_new(const char *name)
>  		goto err;
>  	}
>  
> -	len = strlen(LXCPATH)+strlen(c->name)+strlen("/config")+2;
> +	len = strlen(c->config_path)+strlen(c->name)+strlen("/config")+2;
>  	c->configfile = malloc(len);
>  	if (!c->configfile) {
>  		fprintf(stderr, "Error allocating config file pathname\n");
>  		goto err;
>  	}
> -	ret = snprintf(c->configfile, len, "%s/%s/config", LXCPATH, c->name);
> +	ret = snprintf(c->configfile, len, "%s/%s/config", c->config_path, c->name);
>  	if (ret < 0 || ret >= len) {
>  		fprintf(stderr, "Error printing out config file name\n");
>  		goto err;
> @@ -974,6 +1016,8 @@ struct lxc_container *lxc_container_new(const char *name)
>  	c->get_config_item = lxcapi_get_config_item;
>  	c->get_cgroup_item = lxcapi_get_cgroup_item;
>  	c->set_cgroup_item = lxcapi_set_cgroup_item;
> +	c->get_config_path = lxcapi_get_config_path;
> +	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)) {
> @@ -981,10 +1025,6 @@ struct lxc_container *lxc_container_new(const char *name)
>  		goto err;
>  	}
>  
> -	/*
> -	 * default configuration file is $LXCPATH/$NAME/config
> -	 */
> -
>  	return c;
>  
>  err:
> diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
> index a6fdb2b..32c501e 100644
> --- a/src/lxc/lxccontainer.h
> +++ b/src/lxc/lxccontainer.h
> @@ -18,6 +18,8 @@ struct lxc_container {
>  	int error_num;
>  	int daemonize;
>  
> +	char *config_path;
> +
>  	bool (*is_defined)(struct lxc_container *c);  // did /var/lib/lxc/$name/config exist
>  	const char *(*state)(struct lxc_container *c);
>  	bool (*is_running)(struct lxc_container *c);  // true so long as defined and not stopped
> @@ -58,6 +60,18 @@ struct lxc_container {
>  	int (*get_cgroup_item)(struct lxc_container *c, const char *subsys, char *retv, int inlen);
>  	bool (*set_cgroup_item)(struct lxc_container *c, const char *subsys, const char *value);
>  
> +	/*
> +	 * Each container can have a custom configuration path.  However
> +	 * by default it will be set to either the LXCPATH configure
> +	 * variable, or the lxcpath value in the LXC_GLOBAL_CONF configuration
> +	 * file (i.e. /etc/lxc/lxc.conf).
> +	 * You can change the value for a specific container with
> +	 * set_config_path().  Note there is no other way to specify this in
> +	 * general at the moment.
> +	 */
> +	const char *(*get_config_path)(struct lxc_container *c);
> +	bool (*set_config_path)(struct lxc_container *c, const char *path);
> +
>  #if 0
>  	bool (*commit_cgroups)(struct lxc_container *c);
>  	bool (*reread_cgroups)(struct lxc_container *c);
> diff --git a/src/lxc/utils.c b/src/lxc/utils.c
> index 2a01f8f..b9e6ffc 100644
> --- a/src/lxc/utils.c
> +++ b/src/lxc/utils.c
> @@ -193,3 +193,59 @@ extern int mkdir_p(char *dir, mode_t mode)
>  
>          return 0;
>  }
> +
> +static char *copypath(char *p)
> +{
> +	int len = strlen(p);
> +	char *retbuf;
> +
> +	if (len < 1)
> +		return NULL;
> +	if (p[len-1] == '\n') {
> +		p[len-1] = '\0';
> +		len--;
> +	}
> +	retbuf = malloc(len+1);
> +	if (!retbuf)
> +		return NULL;
> +	strcpy(retbuf, p);
> +	return retbuf;
> +}
> +
> +char *default_lxc_path(void)
> +{
> +	char buf[1024], *p, *retbuf;
> +	FILE *fin;
> +
> +	fin = fopen(LXC_GLOBAL_CONF, "r");
> +	if (fin) {
> +		while (fgets(buf, 1024, fin)) {
> +			if (buf[0] == '#')
> +				continue;
> +			p = strstr(buf, "lxcpath");
> +			if (!p)
> +				continue;
> +			p = strchr(p, '=');
> +			if (!p)
> +				continue;
> +			p++;
> +			while (*p && (*p == ' ' || *p == '\t')) p++;
> +			if (!*p)
> +				continue;
> +			retbuf = copypath(p);
> +			goto out;
> +		}
> +	}
> +	/* we couldn't open the file, or didn't find a lxcpath
> +	 * entry there.  Return @LXCPATH@ */
> +	retbuf = malloc(strlen(LXCPATH)+1);
> +	if (!retbuf)
> +		goto out;
> +	strcpy(retbuf, LXCPATH);
> +
> +out:
> +	if (fin)
> +		fclose(fin);
> +	INFO("returning %s", (retbuf ? retbuf : "null"));
> +	return retbuf;
> +}
> diff --git a/src/lxc/utils.h b/src/lxc/utils.h
> index cfb526e..b24c8fa 100644
> --- a/src/lxc/utils.h
> +++ b/src/lxc/utils.h
> @@ -27,5 +27,10 @@ extern int lxc_copy_file(const char *src, const char *dst);
>  extern int lxc_setup_fs(void);
>  extern int get_u16(unsigned short *val, const char *arg, int base);
>  extern int mkdir_p(const char *dir, mode_t mode);
> +/*
> + * Return a newly allocated buffer containing the default container
> + * path.  Caller must free this buffer.
> + */
> +extern char *default_lxc_path(void);
>  
>  #endif
> diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
> index 90fcafe..5850727 100644
> --- a/src/tests/Makefile.am
> +++ b/src/tests/Makefile.am
> @@ -19,6 +19,7 @@ lxc_test_getkeys_SOURCES = getkeys.c
>  AM_CFLAGS=-I$(top_srcdir)/src \
>  	-DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \
>  	-DLXCPATH=\"$(LXCPATH)\" \
> +	-DLXC_GLOBAL_CONF=\"$(LXC_GLOBAL_CONF)\" \
>  	-DLXCINITDIR=\"$(LXCINITDIR)\"
>  
>  bin_PROGRAMS = lxc-test-containertests lxc-test-locktests lxc-test-startone \
> 


-- 
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: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20130208/d7edeed7/attachment.pgp>


More information about the lxc-devel mailing list