Commit afeecbba by Serge Hallyn Committed by Stéphane Graber

lxc api: fix some config_path oddities

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: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent 35fef4e6
......@@ -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);
......
......@@ -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.
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
......@@ -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
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
/* 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;
}
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment