From 2a59a68183e55e38beedb6442938e31eb7d4749c Mon Sep 17 00:00:00 2001 From: Serge Hallyn Date: Wed, 6 Feb 2013 15:11:19 -0600 Subject: [PATCH] Switch from use of LXCPATH to a configurable default_lxc_path MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Acked-by: Stéphane Graber --- 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 d7ecd0487..e7e3a7e71 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_DEFAULT_CONF, "$defaultconf") 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 5c47aedfa..ae4d9b2eb 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 d8506d349..bada93936 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 40c685e96..2c4d6036d 100644 --- a/src/lxc/commands.c +++ b/src/lxc/commands.c @@ -30,10 +30,13 @@ #include #include #include +#include +#include #include #include #include /* for struct lxc_handler */ +#include #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 63f5567af..bb93189c2 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 7a298c62d..ec73c8f38 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 860b86fb1..fcf34a921 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 cfb332360..18f3d11bd 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 497acbe51..6464e52ae 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 3e95b1630..f338f1230 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 4e92bb0b6..2e44b8df3 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 000000000..3425929ef --- /dev/null +++ b/src/lxc/lxc.functions.in @@ -0,0 +1,35 @@ +#!/bin/sh + +# +# lxc: linux Container library + +# Authors: +# Serge Hallyn + +# 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 9377f4f31..7a926a274 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 1cf9462e9..7561b1b4f 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 b64acffe3..c50c36b7c 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 9d491fcda..6f01645fd 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -30,6 +30,7 @@ #include #include #include +#include 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 a6fdb2ba6..32c501e43 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 2a01f8fe2..b9e6ffc05 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 cfb526ef6..b24c8fac8 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 90fcafee3..58507276b 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 \ -- 2.39.5