]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxc api: fix some config_path oddities
authorSerge Hallyn <serge.hallyn@canonical.com>
Fri, 8 Feb 2013 22:06:32 +0000 (16:06 -0600)
committerStéphane Graber <stgraber@ubuntu.com>
Mon, 11 Feb 2013 04:23:37 +0000 (23:23 -0500)
1. When calling c->set_config_path(), update configfile.  I.e. if we
are setting the config_path to /var/lib/lxc, then the configfile should
be changed to /var/lib/lxc/$container/config

2. Add an optional configpath argument to lxc_container_new.  If NULL,
then the default will be used (as before).  If set, then the passed-in
path will be used.  This way you can do

c1 = lxc.Container("r1", "/var/lib/lxc");
c2 = lxc.Container("r2", "/home/user/lxcbase");

(Note I did *not* implement the python or lua binding to pass that
argument along)

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
15 files changed:
src/lua-lxc/core.c
src/lxc/lxc.h
src/lxc/lxccontainer.c
src/lxc/lxccontainer.h
src/python-lxc/lxc.c
src/tests/Makefile.am
src/tests/containertests.c
src/tests/createtest.c
src/tests/destroytest.c
src/tests/get_item.c
src/tests/getkeys.c
src/tests/lxcpath.c [new file with mode: 0644]
src/tests/saveconfig.c
src/tests/shutdowntest.c
src/tests/startone.c

index ae4d9b2eb96f9b13f93ac8cab5cd486430b2b35b..9225158f4be0143767031486b82dfe4f201bc180 100644 (file)
@@ -44,7 +44,7 @@
 static int container_new(lua_State *L)
 {
     const char *name = luaL_checkstring(L, 1);
-    struct lxc_container *c = lxc_container_new(name);
+    struct lxc_container *c = lxc_container_new(name, NULL);
 
     if (c) {
        lua_boxpointer(L, c);
index 349bbbc0d52de8ae425eff0eb1348afdef279111..a651d04210aed24413511a7bed105f12afb275c6 100644 (file)
@@ -182,7 +182,7 @@ extern const char const *lxc_version(void);
 /*
  * Create and return a new lxccontainer struct.
  */
-extern struct lxc_container *lxc_container_new(const char *name);
+extern struct lxc_container *lxc_container_new(const char *name, const char *configpath);
 
 /*
  * Returns 1 on success, 0 on failure.
index 6f01645fd6d12d6242fbca92ceb9bd4c4fe1d501..733cbb68cbcbad5be83864ca433f3ae28203cbca 100644 (file)
@@ -871,10 +871,45 @@ static const char *lxcapi_get_config_path(struct lxc_container *c)
        return (const char *)(c->config_path);
 }
 
+/*
+ * not for export
+ * Just recalculate the c->configfile based on the
+ * c->config_path, which must be set.
+ * The lxc_container must be locked or not yet public.
+ */
+static bool set_config_filename(struct lxc_container *c)
+{
+       char *newpath;
+       int len, ret;
+
+       if (!c->config_path)
+               return false;
+
+       /* $lxc_path + "/" + c->name + "/" + "config" + '\0' */
+       len = strlen(c->config_path) + strlen(c->name) + strlen("config") + 3;
+       newpath = malloc(len);
+       if (!newpath)
+               return false;
+
+       ret = snprintf(newpath, len, "%s/%s/config", c->config_path, c->name);
+       if (ret < 0 || ret >= len) {
+               fprintf(stderr, "Error printing out config file name\n");
+               free(newpath);
+               return false;
+       }
+
+       if (c->configfile)
+               free(c->configfile);
+       c->configfile = newpath;
+
+       return true;
+}
+
 static bool lxcapi_set_config_path(struct lxc_container *c, const char *path)
 {
        char *p;
        bool b = false;
+       char *oldpath = NULL;
 
        if (!c)
                return b;
@@ -883,13 +918,28 @@ static bool lxcapi_set_config_path(struct lxc_container *c, const char *path)
                return b;
 
        p = strdup(path);
-       if (!p)
+       if (!p) {
+               ERROR("Out of memory setting new lxc path");
                goto err;
+       }
+
        b = true;
        if (c->config_path)
-               free(c->config_path);
+               oldpath = c->config_path;
        c->config_path = p;
+
+       /* Since we've changed the config path, we have to change the
+        * config file name too */
+       if (!set_config_filename(c)) {
+               ERROR("Out of memory setting new config filename");
+               b = false;
+               free(c->config_path);
+               c->config_path = oldpath;
+               oldpath = NULL;
+       }
 err:
+       if (oldpath)
+               free(oldpath);
        lxcunlock(c->privlock);
        return b;
 }
@@ -938,10 +988,9 @@ out:
 }
 
 
-struct lxc_container *lxc_container_new(const char *name)
+struct lxc_container *lxc_container_new(const char *name, const char *configpath)
 {
        struct lxc_container *c;
-       int ret, len;
 
        c = malloc(sizeof(*c));
        if (!c) {
@@ -950,7 +999,11 @@ struct lxc_container *lxc_container_new(const char *name)
        }
        memset(c, 0, sizeof(*c));
 
-       c->config_path = default_lxc_path();
+       if (configpath)
+               c->config_path = strdup(configpath);
+       else
+               c->config_path = default_lxc_path();
+
        if (!c->config_path) {
                fprintf(stderr, "Out of memory");
                goto err;
@@ -976,17 +1029,10 @@ struct lxc_container *lxc_container_new(const char *name)
                goto err;
        }
 
-       len = strlen(c->config_path)+strlen(c->name)+strlen("/config")+2;
-       c->configfile = malloc(len);
-       if (!c->configfile) {
+       if (!set_config_filename(c)) {
                fprintf(stderr, "Error allocating config file pathname\n");
                goto err;
        }
-       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;
-       }
 
        if (file_exists(c->configfile))
                lxcapi_load_config(c, NULL);
index 32c501e4347fc33ccfaf2b64b49a27645f41bf0f..de802a883a9ba28410c2d82e9016d9cd3e4e32ff 100644 (file)
@@ -82,7 +82,7 @@ struct lxc_container {
 #endif
 };
 
-struct lxc_container *lxc_container_new(const char *name);
+struct lxc_container *lxc_container_new(const char *name, const char *configpath);
 int lxc_container_get(struct lxc_container *c);
 int lxc_container_put(struct lxc_container *c);
 int lxc_get_wait_states(const char **states);
index 83e265926a818e530e12394a4cb09e4c8dafbebb..16356f9f554d9fa900895d9b623a31e6b1949863 100644 (file)
@@ -85,7 +85,7 @@ Container_init(Container *self, PyObject *args, PyObject *kwds)
                                       &name))
         return -1;
 
-    self->container = lxc_container_new(name);
+    self->container = lxc_container_new(name, NULL);
     if (!self->container) {
         fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, name);
         return -1;
index 58507276bb571ced7c40945bf7b6aa5888b6f600..a883d3658cac3aac270f69b121f296a03a81c74c 100644 (file)
@@ -15,6 +15,7 @@ lxc_test_createtest_SOURCES = createtest.c
 lxc_test_shutdowntest_SOURCES = shutdowntest.c
 lxc_test_get_item_SOURCES = get_item.c
 lxc_test_getkeys_SOURCES = getkeys.c
+lxc_test_lxcpath_SOURCES = lxcpath.c
 
 AM_CFLAGS=-I$(top_srcdir)/src \
        -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \
@@ -24,6 +25,6 @@ AM_CFLAGS=-I$(top_srcdir)/src \
 
 bin_PROGRAMS = lxc-test-containertests lxc-test-locktests lxc-test-startone \
        lxc-test-destroytest lxc-test-saveconfig lxc-test-createtest \
-       lxc-test-shutdowntest lxc-test-get_item lxc-test-getkeys
+       lxc-test-shutdowntest lxc-test-get_item lxc-test-getkeys lxc-test-lxcpath
 
 endif
index d68f17c7591001074d5cbd381eb0e7771cffd3c9..8868faacb4d5f74bcb0f3275963c35bae6f2b8ef 100644 (file)
@@ -103,7 +103,7 @@ int main(int argc, char *argv[])
 
        ret = 1;
        /* test refcounting */
-       c = lxc_container_new(MYNAME);
+       c = lxc_container_new(MYNAME, NULL);
        if (!c) {
                fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, MYNAME);
                goto out;
@@ -149,7 +149,7 @@ int main(int argc, char *argv[])
        }
 
        /* test a real container */
-       c = lxc_container_new(MYNAME);
+       c = lxc_container_new(MYNAME, NULL);
        if (!c) {
                fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, MYNAME);
                ret = 1;
index 48ce922e68789804f27c6c97cc96502347cf783a..c2abee233af4ec416f6a64c7918302aec6e61e76 100644 (file)
@@ -33,7 +33,7 @@ int main(int argc, char *argv[])
        struct lxc_container *c;
        int ret = 1;
 
-       if ((c = lxc_container_new(MYNAME)) == NULL) {
+       if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
                fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
                ret = 1;
                goto out;
index 28f05772ccbc6ee8e8bf537a67d938cba93d661e..0552b4c05ce299668f1dfcd1777285ad8c833784 100644 (file)
@@ -65,7 +65,7 @@ int main(int argc, char *argv[])
        struct lxc_container *c;
        int ret = 1;
 
-       if ((c = lxc_container_new(MYNAME)) == NULL) {
+       if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
                fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
                ret = 1;
                goto out;
index 0d32eca1e08e177c0d2567071ee9c537711f403f..d3e6d29ad938aa17ca1bb2af04f8a15e6cb4a0bc 100644 (file)
@@ -35,7 +35,7 @@ int main(int argc, char *argv[])
        int ret;
        char v1[2], v2[256], v3[2048];
 
-       if ((c = lxc_container_new("testxyz")) == NULL) {
+       if ((c = lxc_container_new("testxyz", NULL)) == NULL) {
                fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
                ret = 1;
                goto out;
@@ -157,7 +157,7 @@ int main(int argc, char *argv[])
        lxc_container_put(c);
 
        // new test with real container
-       if ((c = lxc_container_new(MYNAME)) == NULL) {
+       if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
                fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
                ret = 1;
                goto out;
@@ -165,7 +165,7 @@ int main(int argc, char *argv[])
        c->destroy(c);
        lxc_container_put(c);
 
-       if ((c = lxc_container_new(MYNAME)) == NULL) {
+       if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
                fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
                ret = 1;
                goto out;
@@ -179,7 +179,7 @@ int main(int argc, char *argv[])
        lxc_container_put(c);
 
        /* XXX TODO load_config needs to clear out any old config first */
-       if ((c = lxc_container_new(MYNAME)) == NULL) {
+       if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
                fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
                ret = 1;
                goto out;
index 9bb559395544ac5701811a9405d9f096c6ec330c..bab68830d59769edd7c1a93f3a4e82fb99f30cea 100644 (file)
@@ -35,7 +35,7 @@ int main(int argc, char *argv[])
        int len, ret;
        char v3[2048];
 
-       if ((c = lxc_container_new(MYNAME)) == NULL) {
+       if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
                fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
                ret = 1;
                goto out;
diff --git a/src/tests/lxcpath.c b/src/tests/lxcpath.c
new file mode 100644 (file)
index 0000000..92525ed
--- /dev/null
@@ -0,0 +1,85 @@
+/* liblxcapi
+ *
+ * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>.
+ * Copyright © 2012 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include "../lxc/lxccontainer.h"
+
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#define MYNAME "lxctest1"
+
+#define TSTERR(x) do { \
+       fprintf(stderr, "%d: %s", __LINE__, x); \
+} while (0)
+
+int main()
+{
+       struct lxc_container *c;
+       const char *p1, *p2;
+       int retval = -1;
+
+       c = lxc_container_new(MYNAME, NULL);
+       if (!c) {
+               TSTERR("create using default path");
+               goto err;
+       }
+       p1 = c->get_config_path(c);
+       p2 = c->config_file_name(c);
+       if (!p1 || !p2 || strncmp(p1, p2, strlen(p1))) {
+               TSTERR("Bad result for path names");
+               goto err;
+       }
+
+#define CPATH "/boo"
+#define FPATH "/boo/lxctest1/config"
+       if (!c->set_config_path(c, "/boo")) {
+               TSTERR("Error setting custom path");
+               goto err;
+       }
+       p1 = c->get_config_path(c);
+       p2 = c->config_file_name(c);
+       if (strcmp(p1, CPATH) || strcmp(p2, FPATH)) {
+               TSTERR("Bad result for path names after set_config_path()");
+               goto err;
+       }
+       lxc_container_put(c);
+
+       c = lxc_container_new(MYNAME, CPATH);
+       if (!c) {
+               TSTERR("create using custom path");
+               goto err;
+       }
+
+       p1 = c->get_config_path(c);
+       p2 = c->config_file_name(c);
+       if (strcmp(p1, CPATH) || strcmp(p2, FPATH)) {
+               TSTERR("Bad result for path names after create with custom path");
+               goto err;
+       }
+
+       retval = 0;
+
+err:
+       lxc_container_put(c);
+       return retval;
+}
index bbaea19b084dc3e7577723c481aa0d83506eba0e..fa84e32140d38161e213369a81a74850b2d3b8b8 100644 (file)
@@ -65,7 +65,7 @@ int main(int argc, char *argv[])
        struct lxc_container *c;
        int ret = 1;
 
-       if ((c = lxc_container_new(MYNAME)) == NULL) {
+       if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
                fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
                ret = 1;
                goto out;
index 9ad8a651048208d93c058a8f8961957f05be4bd6..a1a84e813beaa9027c8be6c82ef476bb18776573 100644 (file)
@@ -34,7 +34,7 @@ int main(int argc, char *argv[])
        struct lxc_container *c;
        int ret = 1;
 
-       if ((c = lxc_container_new(MYNAME)) == NULL) {
+       if ((c = lxc_container_new(MYNAME, NULL)) == NULL) {
                fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME);
                ret = 1;
                goto out;
index f76ed1e67551a721739d16f003964662ad51da16..1eb3e99150c24b3c5b0ccb47db5cdf591603753c 100644 (file)
@@ -103,7 +103,7 @@ int main(int argc, char *argv[])
 
        ret = 1;
        /* test a real container */
-       c = lxc_container_new(MYNAME);
+       c = lxc_container_new(MYNAME, NULL);
        if (!c) {
                fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, MYNAME);
                ret = 1;