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.hal...@ubuntu.com>
Looks good to me. Acked-by: Stéphane Graber <stgra...@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.hal...@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
signature.asc
Description: OpenPGP digital signature
------------------------------------------------------------------------------ Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb
_______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel