From 6c6892b5c5c6281d1e74c979168d1cbbe6a50ffc Mon Sep 17 00:00:00 2001 From: Dwight Engen Date: Tue, 12 Nov 2013 14:04:45 -0500 Subject: [PATCH] fix multithreaded create() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit We were calling save_config() twice within the create() flow, each from a different process. Depending on order of scheduling, sometimes the data from the first save_config() (which was just the stuff from LXC_DEFAULT_CONFIG) would overwrite the config we wanted (the full config), causing a truncated config file which would then cause lxc to segfault once it read it back in because no rootfs.path was set. This fixes it by only calling save_config() once in the create() flow. A rejected alternative was to call fsync(fileno(fout)) before the fclose in save_config. Signed-off-by: Dwight Engen Acked-by: S.Çağlar Onur Signed-off-by: Serge Hallyn --- src/lxc/lxccontainer.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index ede011324..0a94f5e6b 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1192,16 +1192,19 @@ static bool lxcapi_create(struct lxc_container *c, const char *t, if (lxcapi_is_defined(c) && c->lxc_conf && c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) == 0 && tpath) { ERROR("Container %s:%s already exists", c->config_path, c->name); - free(tpath); - return false; + goto free_tpath; } - /* Save the loaded configuration to disk */ - if (!c->save_config(c, NULL)) { - ERROR("failed to save starting configuration for %s\n", c->name); - goto out; + if (!c->lxc_conf) { + if (!c->load_config(c, LXC_DEFAULT_CONFIG)) { + ERROR("Error loading default configuration file %s\n", LXC_DEFAULT_CONFIG); + goto free_tpath; + } } + if (!create_container_dir(c)) + goto free_tpath; + /* * either template or rootfs.path should be set. * if both template and rootfs.path are set, template is setup as rootfs.path. @@ -1290,10 +1293,11 @@ out_unlock: if (partial_fd >= 0) remove_partial(c, partial_fd); out: - if (tpath) - free(tpath); if (!ret && c) lxcapi_destroy(c); +free_tpath: + if (tpath) + free(tpath); return ret; } -- 2.47.2