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.en...@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 ------------------------------------------------------------------------------ Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel