[lxc-devel] [PATCH] fix multithreaded create()

Dwight Engen dwight.engen at oracle.com
Tue Nov 12 19:04:45 UTC 2013


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 <dwight.engen at oracle.com>
---
 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 c7b2f5e..05ca643 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;
 }
 
-- 
1.8.3.1





More information about the lxc-devel mailing list