]> git.proxmox.com Git - mirror_lxc.git/commitdiff
Switch from use of LXCPATH to a configurable default_lxc_path
authorSerge Hallyn <serge.hallyn@canonical.com>
Wed, 6 Feb 2013 21:11:19 +0000 (15:11 -0600)
committerStéphane Graber <stgraber@ubuntu.com>
Fri, 8 Feb 2013 15:55:14 +0000 (10:55 -0500)
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@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
20 files changed:
configure.ac
src/lua-lxc/core.c
src/lxc/Makefile.am
src/lxc/commands.c
src/lxc/conf.c
src/lxc/legacy/lxc-ls.in
src/lxc/lxc-clone.in
src/lxc/lxc-create.in
src/lxc/lxc-destroy.in
src/lxc/lxc-setcap.in
src/lxc/lxc-setuid.in
src/lxc/lxc.functions.in [new file with mode: 0644]
src/lxc/lxc_execute.c
src/lxc/lxc_restart.c
src/lxc/lxc_start.c
src/lxc/lxccontainer.c
src/lxc/lxccontainer.h
src/lxc/utils.c
src/lxc/utils.h
src/tests/Makefile.am

index d7ecd04878a4175c7375fd9b68ccebf091898ca9..e7e3a7e711047d87df85b17388b4968289b31a01 100644 (file)
@@ -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
index 5c47aedfabff37d6566b0210918784b0308baaa8..ae4d9b2eb96f9b13f93ac8cab5cd486430b2b35b 100644 (file)
@@ -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;
 }
 
index d8506d349f095dfb072cb0217448a115d1b77f42..bada9393614b034fa72298ca483a858dc3ec3ac5 100644 (file)
@@ -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); \
index 40c685e96e02e0930a9d8bb7069b4e0f6d5cc29a..2c4d6036d4c9e603185708f0db8d3eb78710dd0f 100644 (file)
 #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"
 
 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) {
index 63f5567afcd871cb4fcff46f6de05dbcc5eb8ae5..bb93189c29cbaacb87a07ef846f6081dbf4173a3 100644 (file)
@@ -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;
 
index 7a298c62d7b8dd467354e820434d114ada339766..ec73c8f38b0619702a45b6fa3de989a1df847cf7 100644 (file)
@@ -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()
 {
index 860b86fb11fe467d60171455535cace0446f3cb4..fcf34a9212214ac0a8944f2c457b0faa087d98bf 100755 (executable)
@@ -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
index cfb332360970ea80f1b396fc547af27881bf2628..18f3d11bdcd36e6aef1c17bb328b5afef4d70e64 100644 (file)
@@ -73,9 +73,7 @@ optarg_check() {
     fi
 }
 
-lxc_path=@LXCPATH@
-bindir=@BINDIR@
-templatedir=@LXCTEMPLATEDIR@
+. @DATADIR@/lxc/lxc.functions
 backingstore=_unset
 fstype=ext4
 fssize=500M
index 497acbe51b043fa2b2e17267b642a085191c3057..6464e52aeb4e329181d81747d7586c5cf31a1d16 100644 (file)
@@ -51,7 +51,7 @@ optarg_check() {
     fi
 }
 
-lxc_path=@LXCPATH@
+. @DATADIR@/lxc/lxc.functions
 force=0
 
 while [ $# -gt 0 ]; do
index 3e95b163019114121df17618caface16384869ab..f338f1230570baa5b0648cdfbf513c945b7c26f0 100644 (file)
@@ -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() {
index 4e92bb0b6da3b7df9076b3a842a3bc6708e964f6..2e44b8df34e3ebcd99889f382ee3cc404ff2001e 100644 (file)
@@ -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 (file)
index 0000000..3425929
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+#
+# lxc: linux Container library
+
+# Authors:
+# Serge Hallyn <serge.hallyn@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`
index 9377f4f31156f7032f41c7a2df19030c084d8934..7a926a274a7e1fb0c169470a763c70e056486dfe 100644 (file)
@@ -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;
index 1cf9462e9395aee690e9866d6bb241fb50a791b4..7561b1b4f702efb01f1e00877a75bace5cf7d022 100644 (file)
@@ -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;
index b64acffe3a52af29a124940e4668bb7d314308db..c50c36b7cec4748f16a08c728c90bb8cdb4a2849 100644 (file)
@@ -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;
index 9d491fcda027b6d31d6a29bd1440fd01416ff639..6f01645fd6d12d6242fbca92ceb9bd4c4fe1d501 100644 (file)
@@ -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:
index a6fdb2ba651759b2d4069cb7b038904787b4cca5..32c501e4347fc33ccfaf2b64b49a27645f41bf0f 100644 (file)
@@ -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);
index 2a01f8fe214d2328f5866f7fad9c3f3094bc6818..b9e6ffc053e44e00fb313d3729ac2fadb7ef5cdf 100644 (file)
@@ -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;
+}
index cfb526ef6a54f417f4944c6e2169c84fb06a5430..b24c8fac8613204365bcd166db37a70e524b97c0 100644 (file)
@@ -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
index 90fcafee30d5938b05586049644e0c935a1be7d1..58507276bb571ced7c40945bf7b6aa5888b6f600 100644 (file)
@@ -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 \