[lxc-devel] [PATCH] Update Lua API, make default_lxc_path const

Dwight Engen dwight.engen at oracle.com
Mon Feb 11 20:12:39 UTC 2013


Add [gs]et_config_path from API to Lua binding. Add additional optional
parameter to container_new(). Add tests for these new Lua API bindings.
Commit 2a59a681 changed the meaning of lxc_path_get() in the binding,
causing lua script breakage. Reinstate original behavior of
lxc_path_get() and rename it to lxc_default_config_path_get() to make
its intent clearer.

Reworked default_lxc_path to compute the default path only once and
return a const char *. Four of the five callers don't need a modifiable
buffer and this saves us from re-parsing the global config file on
every call. This also fixes a leak in fill_sock_name().

Signed-off-by: Dwight Engen <dwight.engen at oracle.com>
---
 src/lua-lxc/core.c           | 37 +++++++++++++++++++++++++++++++------
 src/lua-lxc/lxc.lua          | 18 +++++++++++++++---
 src/lua-lxc/test/apitest.lua | 26 +++++++++++++++++++++++++-
 src/lxc/commands.c           |  2 +-
 src/lxc/conf.c               |  3 +--
 src/lxc/lxc_execute.c        |  3 +--
 src/lxc/lxc_restart.c        |  3 +--
 src/lxc/lxc_start.c          |  5 ++---
 src/lxc/lxccontainer.c       | 11 +++++++++--
 src/lxc/lxccontainer.h       |  1 +
 src/lxc/utils.c              | 19 ++++++++++++-------
 src/lxc/utils.h              |  5 ++---
 12 files changed, 101 insertions(+), 32 deletions(-)

diff --git a/src/lua-lxc/core.c b/src/lua-lxc/core.c
index 9225158..3641786 100644
--- a/src/lua-lxc/core.c
+++ b/src/lua-lxc/core.c
@@ -43,9 +43,15 @@
 
 static int container_new(lua_State *L)
 {
+    struct lxc_container *c;
     const char *name = luaL_checkstring(L, 1);
-    struct lxc_container *c = lxc_container_new(name, NULL);
+    const char *configpath = NULL;
+    int argc = lua_gettop(L);
+
+    if (argc > 1)
+	configpath = luaL_checkstring(L, 2);
 
+    c = lxc_container_new(name, configpath);
     if (c) {
 	lua_boxpointer(L, c);
 	luaL_getmetatable(L, CONTAINER_TYPENAME);
@@ -238,6 +244,25 @@ static int container_save_config(lua_State *L)
     return 1;
 }
 
+static int container_get_config_path(lua_State *L)
+{
+    struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
+    const char *config_path;
+
+    config_path = c->get_config_path(c);
+    lua_pushstring(L, config_path);
+    return 1;
+}
+
+static int container_set_config_path(lua_State *L)
+{
+    struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
+    const char *config_path = luaL_checkstring(L, 2);
+
+    lua_pushboolean(L, !!c->set_config_path(c, config_path));
+    return 1;
+}
+
 static int container_clear_config_item(lua_State *L)
 {
     struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
@@ -326,6 +351,8 @@ static luaL_Reg lxc_container_methods[] =
     {"config_file_name",	container_config_file_name},
     {"load_config",		container_load_config},
     {"save_config",		container_save_config},
+    {"get_config_path",		container_get_config_path},
+    {"set_config_path",		container_set_config_path},
     {"get_config_item",		container_get_config_item},
     {"set_config_item",		container_set_config_item},
     {"clear_config_item",	container_clear_config_item},
@@ -338,18 +365,16 @@ static int lxc_version_get(lua_State *L) {
     return 1;
 }
 
-static int lxc_path_get(lua_State *L) {
-    struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME);
-    const char *lxcpath;
+static int lxc_default_config_path_get(lua_State *L) {
+    const char *lxcpath = lxc_get_default_config_path();
 
-    lxcpath = c->get_config_path(c);
     lua_pushstring(L, lxcpath);
     return 1;
 }
 
 static luaL_Reg lxc_lib_methods[] = {
     {"version_get",		lxc_version_get},
-    {"path_get",		lxc_path_get},
+    {"default_config_path_get",	lxc_default_config_path_get},
     {"container_new",		container_new},
     {NULL, NULL}
 };
diff --git a/src/lua-lxc/lxc.lua b/src/lua-lxc/lxc.lua
index c71de48..b6bc344 100755
--- a/src/lua-lxc/lxc.lua
+++ b/src/lua-lxc/lxc.lua
@@ -107,13 +107,17 @@ container = {}
 container_mt = {}
 container_mt.__index = container
 
-function container:new(lname)
+function container:new(lname, config)
     local lcore
     local lnetcfg = {}
     local lstats = {}
 
     if lname then
-	lcore = core.container_new(lname)
+	if config then
+	    lcore = core.container_new(lname, config)
+	else
+	    lcore = core.container_new(lname)
+	end
     end
 
     return setmetatable({ctname = lname, core = lcore, netcfg = lnetcfg, stats = lstats}, container_mt)
@@ -176,6 +180,14 @@ function container:destroy()
     return self.core:destroy()
 end
 
+function container:get_config_path()
+    return self.core:get_config_path()
+end
+
+function container:set_config_path(path)
+    return self.core:set_config_path(path)
+end
+
 function container:append_config_item(key, value)
     return self.core:set_config_item(key, value)
 end
@@ -408,5 +420,5 @@ function containers_running(names_only)
     return containers
 end
 
-lxc_path = core.path_get()
+lxc_path = core.default_config_path_get()
 cgroup_path = cgroup_path_get()
diff --git a/src/lua-lxc/test/apitest.lua b/src/lua-lxc/test/apitest.lua
index 14d2a9d..1365f91 100755
--- a/src/lua-lxc/test/apitest.lua
+++ b/src/lua-lxc/test/apitest.lua
@@ -22,9 +22,10 @@
 --
 
 local lxc     = require("lxc")
+local lfs     = require("lfs")
 local getopt  = require("alt_getopt")
 
-local LXC_PATH		= lxc.path_get()
+local LXC_PATH		= lxc.default_config_path_get()
 
 local container
 local cfg_containers	= {}
@@ -83,6 +84,28 @@ function test_container_new()
     assert(container:config_file_name() == string.format("%s/%s/config", LXC_PATH, optarg["n"]))
 end
 
+function test_container_config_path()
+    local cfgcontainer
+    local cfgpath = "/tmp/" .. optarg["n"]
+    local cfgname = cfgpath .. "/config"
+
+    log(0, "Test container config path...")
+
+    -- create a config file in the new location from container's config
+    assert(lfs.mkdir(cfgpath))
+    assert(container:save_config(cfgname))
+    cfgcontainer = lxc.container:new(optarg["n"], "/tmp")
+    assert(cfgcontainer ~= nil)
+    log(0, "cfgname:%s cfgpath:%s", cfgcontainer:config_file_name(), cfgcontainer:get_config_path())
+    assert(cfgcontainer:config_file_name() == cfgname)
+    assert(cfgcontainer:get_config_path() == "/tmp")
+    assert(cfgcontainer:set_config_path(LXC_PATH))
+    assert(cfgcontainer:get_config_path() == LXC_PATH)
+
+    assert(os.remove(cfgname))
+    assert(lfs.rmdir(cfgpath))
+end
+
 function test_container_create()
     if (optarg["c"]) then
 	log(0, "%-20s %s", "Destroy existing container:", optarg["n"])
@@ -280,6 +303,7 @@ test_container_new()
 test_container_create()
 test_container_stopped()
 test_container_in_cfglist(true)
+test_container_config_path()
 
 test_config_items()
 test_config_keys()
diff --git a/src/lxc/commands.c b/src/lxc/commands.c
index 2c4d603..ea1a9b2 100644
--- a/src/lxc/commands.c
+++ b/src/lxc/commands.c
@@ -60,7 +60,7 @@
 lxc_log_define(lxc_commands, lxc);
 
 static int fill_sock_name(char *path, int len, const char *name) {
-	char *lxcpath = default_lxc_path();
+	const char *lxcpath = default_lxc_path();
 	int ret;
 	if (!lxcpath) {
 		ERROR("Out of memory getting lxcpath");
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index bb93189..04ab8b8 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1519,7 +1519,7 @@ static int mount_entry_on_absolute_rootfs(struct mntent *mntent,
 	unsigned long mntflags;
 	char *mntdata;
 	int r, ret = 0, offset;
-	char *lxcpath;
+	const char *lxcpath;
 
 	if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
 		ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
@@ -1535,7 +1535,6 @@ static int mount_entry_on_absolute_rootfs(struct mntent *mntent,
 	/* if rootfs->path is a blockdev path, allow container fstab to
 	 * 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/lxc_execute.c b/src/lxc/lxc_execute.c
index 7a926a2..0c620e5 100644
--- a/src/lxc/lxc_execute.c
+++ b/src/lxc/lxc_execute.c
@@ -109,14 +109,13 @@ int main(int argc, char *argv[])
 		rcfile = (char *)my_args.rcfile;
 	else {
 		int rc;
-		char *lxcpath = default_lxc_path();
+		const char *lxcpath = default_lxc_path();
 		if (!lxcpath) {
 			ERROR("Out of memory");
 			return -1;
 		}
 
 		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 7561b1b..eb41033 100644
--- a/src/lxc/lxc_restart.c
+++ b/src/lxc/lxc_restart.c
@@ -132,14 +132,13 @@ int main(int argc, char *argv[])
 		rcfile = (char *)my_args.rcfile;
 	else {
 		int rc;
-		char *lxcpath = default_lxc_path();
+		const char *lxcpath = default_lxc_path();
 		if (!lxcpath) {
 			ERROR("Out of memory");
 			return -1;
 		}
 
 		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 c50c36b..6e17aa6 100644
--- a/src/lxc/lxc_start.c
+++ b/src/lxc/lxc_start.c
@@ -173,19 +173,18 @@ int main(int argc, char *argv[])
 		rcfile = (char *)my_args.rcfile;
 	else {
 		int rc;
-		char *lxcpath = default_lxc_path();
+		const char *lxcpath = default_lxc_path();
 		if (!lxcpath) {
 			ERROR("Out of memory");
 			return -1;
 		}
 
 		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;
 		}
+		INFO("using rcfile %s", rcfile);
 
 		/* container configuration does not exist */
 		if (access(rcfile, F_OK)) {
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 733cbb6..d7170ee 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -987,6 +987,10 @@ out:
 	return ret;
 }
 
+const char *lxc_get_default_config_path(void)
+{
+	return default_lxc_path();
+}
 
 struct lxc_container *lxc_container_new(const char *name, const char *configpath)
 {
@@ -1001,8 +1005,11 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
 
 	if (configpath)
 		c->config_path = strdup(configpath);
-	else
-		c->config_path = default_lxc_path();
+	else {
+		const char *lxcpath = default_lxc_path();
+		if (lxcpath)
+			c->config_path = strdup(lxcpath);
+	}
 
 	if (!c->config_path) {
 		fprintf(stderr, "Out of memory");
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
index de802a8..f0c4565 100644
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -86,6 +86,7 @@ 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);
+const char *lxc_get_default_config_path(void);
 
 #if 0
 char ** lxc_get_valid_keys();
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index b9e6ffc..443716f 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -212,10 +212,14 @@ static char *copypath(char *p)
 	return retbuf;
 }
 
-char *default_lxc_path(void)
+const char *default_lxc_path(void)
 {
-	char buf[1024], *p, *retbuf;
-	FILE *fin;
+	char buf[1024], *p;
+	FILE *fin = NULL;
+	static const char *retbuf;
+
+	if (retbuf)
+		goto out;
 
 	fin = fopen(LXC_GLOBAL_CONF, "r");
 	if (fin) {
@@ -238,10 +242,11 @@ char *default_lxc_path(void)
 	}
 	/* 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);
+	p = malloc(strlen(LXCPATH)+1);
+	if (p) {
+		strcpy(p, LXCPATH);
+		retbuf = p;
+	}
 
 out:
 	if (fin)
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index b24c8fa..00c818c 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -28,9 +28,8 @@ 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.
+ * Return a buffer containing the default container path.
  */
-extern char *default_lxc_path(void);
+extern const char *default_lxc_path(void);
 
 #endif
-- 
1.7.12.3





More information about the lxc-devel mailing list